Issued orders are purchase orders WE send - they must pick from suppliers
(sklad_suppliers), not from customers. Per user decision customer_id was
REPLACED (not kept alongside): migration drops issued_orders.customer_id and
adds supplier_id FK -> sklad_suppliers (existing rows lose their counterparty
- the feature is days old; re-point them in the UI).
- service: input/filters/search (suppliers.name + ico)/enrichment/detail all
supplier-based; create validates the supplier inside the transaction and
update before write -> Czech 400 'Dodavatel nenalezen' instead of P2003 500;
detail returns a minimal supplier field set (no internal notes leak)
- routes: supplier_id on list + stats; new GET /issued-orders/suppliers
lookup (orders.view/create/edit guard - orders users lack warehouse.manage
which guards the warehouse suppliers CRUD), active suppliers only,
name+id ordering
- PDF: Dodavatel block now renders the supplier (name, newline-split address,
IC/DIC), layout and both language label sets unchanged
- frontend: new SupplierPicker kit component (CustomerPicker untouched),
IssuedOrderDetail/IssuedOrders switched to supplier_id/supplier_name; the
picker keeps a fallback option for orders whose supplier was later
deactivated; WarehouseSuppliers CRUD now also invalidates issued-orders so
the picker can't go stale
- tests: issued-orders suite switched to supplier fixtures + new coverage
(lookup shape + 403, nonexistent supplier 400, PDF supplier block)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fixes every CRITICAL/HIGH finding from the 2026-06-09 full-codebase audit
(REVIEW_FINDINGS.md); each fix went through independent spec + code-quality
review. Plan and per-task log: docs/superpowers/plans/2026-06-10-audit-high-fix-pass.md
- attendance: schemas accept the combined local datetimes the forms/service
use (new dateTimeString helpers in schemas/common.ts), breaks persist on
create, AttendanceCreate submit rebuilt — every submit 400'd since 519edce
- 2fa: backup codes wired to /totp/backup-verify (+ remember-me parity),
enrollment QR generated locally via qrcode (CSP-blocked external service
also leaked the secret), dashboard shows per-user enrollment, not policy
- invoices/orders: per-line VAT survives re-saves (numberOr 0-respecting
coercion in formatters.ts), billing_text persists on update, issued-order
status transitions update UI gates
- trips: real pagination on all 3 pages, GET /trips/stats server aggregate
(shared buildTripsWhere + legacy distance coalesce), vehicle_id applies on
PUT with both-vehicle odometer recompute, print rebuilt (sync window.open,
escaped template, server totals)
- orders api: attachment_data PDF blob excluded from all non-binary reads
- warehouse: unit field is a Select over UnitEnum, receipt attachments
downloadable via new authenticated GET route
- downloads: shared RFC 5987 contentDisposition helper — Czech filenames no
longer 500 (warehouse, received-invoices, orders endpoints)
- misc: block-env hook actually blocks (exit 2 + stderr), project create
works with empty dates, NaN filter guards on trips endpoints
- deps: remove unused concurrently (clears both critical advisories), pin
@hono/node-server >=1.19.13 via overrides (clears the 3 moderates without
the Prisma 6 downgrade), drop deprecated @types stubs
Gates: tsc -b clean - vitest 30 files / 342 tests (31 new) - eslint 0 errors
- build OK
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Issued-order PDF: drop the Vystavil/Schválil signature row; footer now shows
'Vystavil: <name>' + 'E-mail: <email>' from the logged-in user (authData).
- IssuedOrderDetail PDF button 'Export PDF' -> 'Zobrazit objednávku' (already
opens inline like invoices' 'Zobrazit fakturu').
- New /orders/stats + /issued-orders/stats endpoints sum order total (incl VAT)
per currency across the active filter; rendered as 'Celkem: …' beneath both
the received and issued lists. formatMultiCurrency lifted to a shared util.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
offers.export/orders.export/invoices.export gated nothing on the backend (PDF
routes enforce *.view); they only toggled frontend buttons and showed dead
role checkboxes. Migration deletes them (+ role grants) and idempotently seeds
the 12 enforced doc perms (offers/orders/invoices x view/create/edit/delete) +
admin grant, so a fresh prod DB has them (closes the seed-only drift gap).
Route reverts to orders.view; the 8 frontend *.export checks now use *.view.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bug 1: creating an issued order as 'sent' redirected to the detail which showed
'Koncept' until a refresh — the component is reused across create→edit, so the
one-shot hydration (gated by dataReady) never reloaded the real status. Now the
just-saved status is reflected into local form state on every save with a target.
Bug 2: both edit-draft buttons shared one 'saving' flag, so pressing 'Uložit
koncept' made 'Odeslat' show 'Ukládání...'. Track which action is in flight so
only the clicked button spins (all stay disabled to block double-submit).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replaces MUI autosize (no handle, mis-wraps in table cells) with a fixed 2-row textarea + resize:vertical so the box wraps and the user can drag it taller. Restores the dead '& input' sx as '& textarea'.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The editable unit-price number input was cramped (5.5rem, same as qty/unit); widened to 8rem to match the Celkem column and the read-only detail view, so real prices fit.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>