import { beforeEach, describe, expect, it } from 'vitest'; import { isEncryptedField } from '@bytelyst/field-encrypt'; import { getCollection } from './datastore.js'; import { _resetEncryptor } from './field-encrypt.js'; import { resetMemoryDatastore } from '../test-helpers.js'; import { createNoteArtifact, getNoteArtifact } from '../modules/note-artifacts/repository.js'; import type { NoteArtifactDoc } from '../modules/note-artifacts/types.js'; import { createPromptTemplate, getPromptTemplate } from '../modules/note-prompts/repository.js'; import type { PromptTemplateDoc } from '../modules/note-prompts/types.js'; import { createNoteAgentAction, getNoteAgentAction, updateNoteAgentAction, } from '../modules/note-agent-actions/repository.js'; import type { NoteAgentActionDoc } from '../modules/note-agent-actions/types.js'; describe('field encryption coverage', () => { beforeEach(() => { resetMemoryDatastore(); _resetEncryptor(); }); it('encrypts sensitive artifact metadata while returning plaintext to callers', async () => { const created = await createNoteArtifact({ id: 'artifact-1', productId: 'notelett', workspaceId: 'ws-1', userId: 'user-1', noteId: 'note-1', artifactType: 'summary', title: 'Private summary', description: 'Sensitive extracted summary', blobPath: 'notelett/user-1/private-summary.md', contentType: 'text/markdown', createdAt: '2026-05-05T00:00:00.000Z', createdBy: 'user-1', updatedAt: '2026-05-05T00:00:00.000Z', updatedBy: 'user-1', }); expect(created.title).toBe('Private summary'); expect(created.description).toBe('Sensitive extracted summary'); const raw = await getCollection('note_artifacts', '/workspaceId').findById('artifact-1', 'ws-1'); expect(isEncryptedField(raw?.title)).toBe(true); expect(isEncryptedField(raw?.description)).toBe(true); expect(isEncryptedField(raw?.blobPath)).toBe(true); const fetched = await getNoteArtifact('artifact-1', 'ws-1'); expect(fetched).toMatchObject({ title: 'Private summary', description: 'Sensitive extracted summary', blobPath: 'notelett/user-1/private-summary.md', }); }); it('encrypts custom prompt content while preserving slug lookup', async () => { const created = await createPromptTemplate('user-1', { slug: 'private-template', name: 'Private Template', description: 'Internal reasoning instructions', systemPrompt: 'Use confidential house style.', userPromptTemplate: 'Rewrite {{note}} for leadership.', inputType: 'text', outputType: 'new_note', category: 'transform', requiresApproval: true, }); expect(created.systemPrompt).toBe('Use confidential house style.'); expect(created.userPromptTemplate).toBe('Rewrite {{note}} for leadership.'); const raw = await getCollection('note_prompts', '/userId').findById(created.id, 'user-1'); expect(raw?.slug).toBe('private-template'); expect(isEncryptedField(raw?.description)).toBe(true); expect(isEncryptedField(raw?.systemPrompt)).toBe(true); expect(isEncryptedField(raw?.userPromptTemplate)).toBe(true); const fetched = await getPromptTemplate(created.id, 'user-1'); expect(fetched).toMatchObject({ slug: 'private-template', description: 'Internal reasoning instructions', systemPrompt: 'Use confidential house style.', userPromptTemplate: 'Rewrite {{note}} for leadership.', }); }); it('encrypts agent action details and review notes while preserving query metadata', async () => { await createNoteAgentAction({ id: 'action-1', productId: 'notelett', workspaceId: 'ws-1', userId: 'user-1', noteId: 'note-1', actorId: 'agent-1', actorType: 'agent', toolName: 'notes.notes.update', actionType: 'update', state: 'proposed', reason: 'Agent proposed a sensitive rewrite', beforeSummary: 'Original private note', afterSummary: 'Rewritten private note', idempotencyKey: 'idem-1', correlationId: 'corr-1', createdAt: '2026-05-05T00:00:00.000Z', createdBy: 'user-1', updatedAt: '2026-05-05T00:00:00.000Z', updatedBy: 'user-1', }); await updateNoteAgentAction('action-1', 'ws-1', { state: 'approved', reviewNote: 'Approved after private review', updatedAt: '2026-05-05T01:00:00.000Z', updatedBy: 'user-1', }); const raw = await getCollection('note_agent_actions', '/workspaceId').findById('action-1', 'ws-1'); expect(raw?.toolName).toBe('notes.notes.update'); expect(raw?.idempotencyKey).toBe('idem-1'); expect(isEncryptedField(raw?.reason)).toBe(true); expect(isEncryptedField(raw?.beforeSummary)).toBe(true); expect(isEncryptedField(raw?.afterSummary)).toBe(true); expect(isEncryptedField(raw?.reviewNote)).toBe(true); const fetched = await getNoteAgentAction('action-1', 'ws-1'); expect(fetched).toMatchObject({ reason: 'Agent proposed a sensitive rewrite', beforeSummary: 'Original private note', afterSummary: 'Rewritten private note', reviewNote: 'Approved after private review', }); }); });