fix(mcp): include payload_hash in post_delivery's journal row

PocketBase requires it on mcp_operations; the in-memory test database
did not, so post_delivery failed on live data with 'Failed to create record'.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
DEls 2026-10-09 07:37:29 +02:00
parent 6999c0a6dc
commit 46452ce48f
2 changed files with 3 additions and 3 deletions

View file

@ -27,7 +27,7 @@ it('posts every planned line, closes NIL lines and journals the result',async()=
expect(post).toHaveBeenCalledTimes(2);
expect(post.mock.calls[1][1].body.confirmation).toMatchObject({disposition:'not_delivered'});
expect(r.result).toMatchObject({complete:true});
expect([...store('mcp_operations').values()][0]).toMatchObject({status:'committed',tool:'post_delivery'});
expect([...store('mcp_operations').values()][0]).toMatchObject({status:'committed',tool:'post_delivery',payload_hash:expect.stringMatching(/^[a-f0-9]{64}$/)});
});
it('refuses before posting when a delivered line is not planned',async()=>{
const {ctx}=await setup([alloc([0]),alloc([1])],[5,3]);

View file

@ -16,7 +16,7 @@
*/
import {z} from 'zod';
import type {PurchasingContext,OperationResult} from './types';
import {MutationSchema,operationRecordId} from './operations';
import {MutationSchema,operationPayloadHash,operationRecordId} from './operations';
import {RecordId} from './documents';
import {PurchasingError,describePurchasingError} from './errors';
import {withResourceLease} from './resource-lease';
@ -39,7 +39,7 @@ export async function postDelivery(ctx:PurchasingContext,input:Record<string,unk
const journalId=operationRecordId(ctx.principal.id,'post_delivery',args.operationId);
const prior=await ctx.pb.collection('mcp_operations').getOne(journalId).catch(()=>null);
if(prior?.status==='committed')return {operationId:args.operationId,status:'committed',result:(prior.result??null) as Record<string,unknown>|null};
if(!prior)await ctx.pb.collection('mcp_operations').create({id:journalId,credential:ctx.principal.id,tool:'post_delivery',operation_id:args.operationId,status:'pending'});
if(!prior)await ctx.pb.collection('mcp_operations').create({id:journalId,credential:ctx.principal.id,tool:'post_delivery',operation_id:args.operationId,payload_hash:operationPayloadHash('post_delivery',args),status:'pending'});
const note=await ctx.pb.collection('dn_batch_notes').getOne(args.id);
if(note.batch!==args.batchId)throw new PurchasingError('candidate_batch_mismatch');
if(!note.purchase_order||!note.supplier)throw new PurchasingError('candidate_entities_unresolved',409);