import { strict as assert } from 'node:assert'; import { describe, it } from 'node:test'; import { z } from 'zod'; import type { Database } from '@pig/db'; import type { Principal } from '../src/lib/auth'; import { AuthError } from '../src/lib/auth'; import { apiError, executeMutation, MutationError } from '../src/lib/mutation'; const principal: Principal = { userId: '00000000-0000-0000-0000-000000000001', email: 'seller@example.com', name: 'Seller', isPlatformAdmin: false, teams: [{ team: 'demand', role: 'member' }], via: 'jwt', scopes: ['read', 'write'], }; function fakeDatabase(events: string[], activityRows: unknown[]): Database { const tx = { insert: () => ({ values: async (row: unknown) => { events.push('activity'); activityRows.push(row); }, }), }; return { transaction: async (work: (transaction: unknown) => Promise) => { events.push('transaction'); return work(tx); }, } as unknown as Database; } describe('mutation convention', () => { it('checks capability before reading attacker-controlled input', async () => { const events: string[] = []; const forbidden = { ...principal, teams: [{ team: 'supply', role: 'admin' }] } as Principal; await assert.rejects( executeMutation(fakeDatabase(events, []), forbidden, async () => { events.push('body'); return {}; }, { schema: z.object({ name: z.string() }), permission: { capability: 'deal:write', team: 'demand' }, invalidMessage: 'Invalid deal.', async mutate() { events.push('mutate'); return { data: {}, activity: { type: 'note', subject: 'Changed' } }; }, }), (error: unknown) => error instanceof AuthError && error.code === 'insufficient_permission', ); assert.deepEqual(events, []); }); it('rejects invalid ontology input before opening a transaction', async () => { const events: string[] = []; const stages = ['qualification', 'legal'] as const; await assert.rejects( executeMutation(fakeDatabase(events, []), principal, async () => ({ stage: 'invented' }), { schema: z.object({ stage: z.enum(stages) }), permission: { capability: 'deal:write', team: 'demand' }, invalidMessage: 'Invalid transition.', async mutate() { events.push('mutate'); return { data: {}, activity: { type: 'stage_change', subject: 'Changed' } }; }, }), (error: unknown) => error instanceof MutationError && error.code === 'invalid_request' && apiError(error.code, error.message, error.issues).issues?.length === 1, ); assert.deepEqual(events, []); }); it('writes mutation evidence in the same transaction with framework attribution', async () => { const events: string[] = []; const rows: unknown[] = []; const result = await executeMutation( fakeDatabase(events, rows), principal, async () => ({ stage: 'legal' }), { schema: z.object({ stage: z.literal('legal') }), permission: { capability: 'deal:write', team: 'demand' }, invalidMessage: 'Invalid transition.', async mutate() { events.push('mutate'); const data = { id: 'deal-1' }; return { data, activity: { type: 'stage_change', subject: 'Moved to legal', demandDealId: data.id, }, }; }, }, ); assert.deepEqual(result, { id: 'deal-1' }); assert.deepEqual(events, ['transaction', 'mutate', 'activity']); assert.deepEqual(rows, [ { type: 'stage_change', subject: 'Moved to legal', demandDealId: 'deal-1', actorUserId: principal.userId, actorAgent: null, source: 'manual', occurredAt: (rows[0] as { occurredAt: Date }).occurredAt, }, ]); assert.ok((rows[0] as { occurredAt: unknown }).occurredAt instanceof Date); }); });