🩺 System Diagnostics

No login required for this page on purpose — so it still loads even if something else is broken. It reveals no passwords or secrets, only pass/fail checks.

PHP version8.4.24 ✅
pdo_mysql extensionloaded ✅
config/config.php loads without erroryes ✅
APP_BASE_PATH (from .env)/forex-bureau
Database connectionconnected ✅
Database has expected tables25 tables found ✅
role_permissions table has rows71 rows ✅
users table has at least one active user3 active user(s) ✅
core/Config.php exists (confirms current code)yes ✅
core/helpers.php uses Config (not a direct require)current ✅
Build: 2026-07-14-phase4-12 Includes everything from phase4-11, PLUS: found the ACTUAL root cause of the transaction_number collision — not a race condition at all. PHP's clock (Africa/Dar_es_Salaam, UTC+3) and MySQL's clock (UTC on Bluehost) disagreed about what day it was for roughly 3 hours every single day. The transaction number's embedded date came from PHP's date(), while the transaction_date column came from MySQL's CURDATE() — during that 3-hour window, PHP thought it was already Aug 2 while MySQL's CURDATE() still said Aug 1, so the "how many transactions today" count query (filtered by MySQL's CURDATE()) came up empty even though rows existed, generating 00001 again and colliding with a real row that already had that number. Fixed at the root: the DB connection now aligns MySQL's session timezone with the app's configured timezone, so CURDATE()/NOW() always agree with PHP's date()/time() everywhere in the app, not just for transaction numbers -- this was a latent bug in till sessions, daily closing, and cash books too. No database changes needed. If /diagnostics does not load, or shows a different build string than the one at the top of this file, you are not running these files — re-extract the zip completely.

← Back to login