get_document_totals gains type=received_invoices: whole-set gross sums per
currency + total_czk via the same toCzk logic as the stats route (unknown
currencies skipped + reported), month/year via the literal columns (bare
year supported), unpaid/paid filter, period echo. invoices.view joined the
coarse gate (the per-type re-check keeps other families locked); the tool
description routes 'kolik jsme utratili' questions here.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- SPZ matching normalized on both sides (4SY7039 finds '4SY 7039') in
list_vehicles and the list_trips vehicle filter; JS-side name matching
diacritic-folded to keep utf8mb4_unicode_ci parity; ICO typed with spaces
matches the space-less stored value (suppliers + customers)
- get_top_customers: whole-table per-customer counts of invoices (sans
drafts) / orders / projects, top 20 + customers_with_records, optional
year, per-type permission re-checks — answers 'pro koho pracujeme nejvic'
exactly instead of refusing
- find_employee, find_supplier and stock search now return total_matching
(stock search also gained its missing deterministic orderBy); system
prompt teaches the model to answer counts from total_matching and use
aggregation tools instead of summing 20-row list pages
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Seven read-only tools: leave balance (own/attendance.balances parity), work
fund + overtime (getWorkfund), project hours report (attendance.manage),
supplier lookup (inactive only for warehouse.manage — picker-route parity),
vehicles with the route's odometer rule, whole-set document totals per
currency (fixes the sum-of-20-list-rows trap; bare month defaults the year
and the applied period is echoed — adversarial review caught the silent
all-time-as-monthly figure), and received-invoice detail with match count.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Five read-only detail tools (offer, order, issued order, invoice, project)
looked up by document number (partial match). They call the same getX(id)
services the detail routes use under the same .view permissions (parity
verified route-by-route), and return compact payloads: line items capped at
50 rows with full totals, is_included_in_total respected, rich text
stripped to plain excerpts, invoice VAT broken down per the editor rule
(per-item rate + apply_vat).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The system prompt now lists the data areas the caller's permissions filtered
out, so the model tells the user explicitly they lack rights to that module
(and can ask the admin) instead of guessing the feature does not exist or
pointing them at a module they cannot open. Tool-less users get the same
explicit phrasing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A failed call followed by a successful retry showed two identical chips
(one orange). Retries are loop mechanics: the trace now carries one entry
per tool with ok = delivered-at-least-once, for live chips and persisted
history alike (also keeps meta.tools under its 30-entry cap).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- find_employee: name -> user_id with route-parity population scoping
(attendance perms see plan users, trips perms see drivers sans usernames,
full directory only with users.view; trips.history unlocks nothing)
- get_attendance_summary: day-range detail with worked hours (shared
calcWorkedHours, break subtracted) + totals; attendance.manage also
unlocks the tool
- list_trips: kniha jizd with route-identical non-manager self-scoping and
the stats-endpoint km coalesce; bare month defaults to current year
- get_work_plan: resolved plan grid rows; off-grid users need
attendance.manage (grid-route parity)
- executeTool flags handler {error} results not-ok (consistent denial chips)
- system prompt: resolve employee names via find_employee first (gated on
the tool being present)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>