feat(mcp): dimension parity for the write/read tool edges (#1274)

Closes the MCP dimension gaps found in the 2026-07-28 audit:

- gnubok_bulk_book_inbox_items accepts a shared dimensions bag through
  all three layers (tool schema + BulkBookInboxSchema + categorize-core
  BulkBookInboxInput), resolve-don't-select with echoed resolutions; the
  web inbox bulk-book route and the pending-op executor inherit it via
  the shared schema.
- gnubok_create_employee / gnubok_update_employee accept
  default_dimensions (names resolve to codes; {} clears on update).
  The command layer already persisted the field: only the MCP boundary
  blocked it, leaving payroll tagging dashboard-only.
- gnubok_query_journal: dimensions bag filter (jsonb containment via
  the GIN index, covers custom dims the legacy project/cost_center
  filters cannot) + include_dimensions to return each line's bag.
  The wide full-match fetch stays dims-free unless something needs it.
- gnubok_list_invoices / gnubok_list_supplier_invoices return
  default_dimensions (agents could set invoice bags but never read
  them back).
- Discoverability: create_voucher, categorize_transaction,
  correct_entry, update_invoice descriptions now name dimensions;
  categorize_month and invoice_run loadouts include
  gnubok_list_dimensions. Trimmed new schema prose to stay under the
  tools/list payload budget.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-07-29 09:39:53 +02:00
committed by GitHub
co-authored by Claude Fable 5
parent 222e581476
commit 80a14ddfd2
8 changed files with 418 additions and 13 deletions
+4
View File
@@ -1376,6 +1376,10 @@ export const BulkBookInboxSchema = z.object({
vat_amount: z.number().positive().nullish().transform((v) => v ?? undefined),
notes: z.string().max(2000).nullish().transform((v) => v ?? undefined),
allow_duplicate: z.boolean().nullish().transform((v) => v ?? undefined),
// Shared dimensions bag applied to the business lines of every generated
// verifikat (same semantics as single categorize). nullish for the same
// staged-params reason as the fields above.
dimensions: DimensionsBagSchema.nullish().transform((v) => v ?? undefined),
})
export type BulkBookInboxInput = z.infer<typeof BulkBookInboxSchema>