- sign-in pages load only what they use (include_login_header.php, ajax_core.js)
- every library, font and data file served from assets/vendor with pinned
versions (VERSIONS.json); no CDN at runtime
- Content-Security-Policy on app, sign-in and landing pages
- remove httpbin Dropzone target and source-map references
- users, SMTP and batch-lock endpoints are owner/admin only
- engines answer 400/403/404/409/500 instead of 200 with an error body;
database errors no longer leak to the client
Validate document lines on the server and recompute their totals, store notes with quotes/markup/emoji (utf8mb4, idempotent escaping, decode in form fields), exclude transfers from company-wide stock in/out, count revenue from confirmed orders only, one low-stock rule everywhere, list unapproved lots, natural bin sort, stable order/PO sort, status tiles that add up.
Return JSON from any uncaught engine exception, stop the empty stock-out warehouse list aborting page boot, reject non-transfer rows in the transfer lookup, define the missing reset_input helper, and remove a stale unreferenced copy of confirm_order.php.
Send journal lines, gl_id and list filters inside the ajax data payload where ajax_request reads them, select period when replacing a manual journal, and show ledger amounts to two decimals.
Stock Transfer list showed 0.00 (read in instead of out); stock-out/transfer forms show the location quantity; dates display as YYYY-MM-DD HH:mm:ss. Demo seeds map product accounts and use product names and supplier batches.