# System And Settings Features ## Authentication Routes: - `app/login/index.php` - `app/login/register.php` - `app/login/verify.php` - `app/login/forgot_password.php` - `app/login/onboarding.php` - `app/login/api/engine/*` Authentication supports registration, login, OTP confirmation, password reset, onboarding, and app branch selection. Backend support: - `PasswordManager` - `PasswordResetManager` - Login APIs under `app/login/api/engine` ## Session And Security Core files: - `app/session.php` - `app/assets/utils/db_auth.php` - `app/assets/utils/db_helpers.php` Security behavior: - Authenticated session required for normal API routes. - POST routes validate CSRF token. - OTP freshness is checked against the user's current password. - Company access is validated through `company_map_user`. - API payloads are accepted as JSON-wrapped POST or FormData. - Role checks use `require_role()`. ## User Management Routes: - `app/setting/users.php` - `app/setting/api/engine/manage_users.php` - `app/setting/api/engine/search_users.php` - `app/setting/api/engine/retrieve_users.php` User management supports company users, invitation, role updates, and user removal. Backend support: - `UserManager::getCompanyUsers()` - `UserManager::searchUsers()` - `UserManager::inviteUser()` - `UserManager::updateRole()` - `UserManager::removeUser()` ## Profile And Password Routes: - `app/setting/profile.php` - `app/setting/api/engine/manage_profile.php` - `app/setting/api/engine/change_password.php` - `app/setting/api/engine/request_reset_otp.php` - `app/setting/api/engine/reset_password_otp.php` Users can maintain profile details and change/reset passwords. Backend support: - `UserManager::getProfile()` - Password reset managers and setting APIs ## Company Settings Routes: - `app/setting/company.php` - `app/setting/system_config.php` - `app/setting/api/engine/company_setting.php` - `app/setting/api/engine/manage_company.php` - `app/setting/api/engine/retrieve_company.php` Company settings store transaction configuration, posting windows, system behavior toggles, branch/company details, and setup values. System configuration includes: - Advanced Location: simple location mode or three-level zone/aisle/rack mode. - Location Labels: custom labels for warehouse location levels. - Default Stock Status: draft or auto-approved stock entries. - Auto-Complete on Shipped: whether shipped orders become completed automatically. - Invoice and Credit Note Generation: automatic invoice on order confirmation and credit note on return confirmation. - Setting Locks: selected settings become locked after dependent transactions exist. Backend support: - `CompanySettingManager` ## SMTP Settings Routes: - `app/setting/smtp.php` - `app/setting/api/engine/manage_smtp.php` - `app/setting/api/engine/retrieve_smtp.php` - `app/setting/api/engine/test_smtp.php` - `app/assets/utils/module/mailer.php` SMTP settings configure outbound email and include a test route. ## Branch Switching Routes: - `app/setting/api/engine/switch_branch.php` - `app/include_topbar.php` Branch switching changes the active company/context for a logged-in user when they have access to more than one company. Backend support: - `UserManager::getCompanyList()` ## Shared JavaScript Utilities File: - `app/assets/js/custom.js` Shared frontend utilities include: - `ajax_request()` with CSRF headers, loading overlay, queue lock, JSON payload preparation, and FormData handling. - `generate_pagination()` for table paging. - `batch_process()` for retryable sequential batch jobs. - Operation lock helpers (`acquire_op_lock` / `release_op_lock`) for long-running cross-tab operations — wraps `OperationLockManager` (see below). - Account autocomplete for posting-account selection. - Number formatting that avoids scientific notation and suppresses tiny floating point noise. ## Operation Locks Routes: - `app/accounting/api/engine/acquire_op_lock.php` - `app/accounting/api/engine/release_op_lock.php` Operation locks prevent two users (or two browser tabs) from running the same long-running operation simultaneously. A lock is a DB row in `operation_locks` with a `company_id`, `operation_type`, `user_id`, and expiry timestamp. Behavior: - `acquire()` inserts or refreshes a lock row. Returns `{ acquired: true }` if successful or `{ acquired: false, held_by: '...' }` if another user holds it. - `release()` deletes the lock row for the calling user. - Locks have a configurable TTL (default 120 minutes). Expired locks are treated as unowned — any user can acquire them even without an explicit release. Currently used for: - `gl_post` — Batch GL posting in `accounting/gl_entries.php`. Prevents two users from running overlapping batch jobs against the same company's GL. Backend support: - `OperationLockManager::acquire(string $operation_type, int $ttl_minutes = 120)` - `OperationLockManager::release(string $operation_type)` ## ETL Summary Maintenance Routes: - `app/setting/gl_maintenance.php` - `app/setting/stock_maintenance.php` - `app/setting/api/engine/gl_maintenance.php` - `app/setting/api/engine/stock_maintenance.php` - `app/cron/etl_gl_maintenance.php` - `app/cron/etl_stock_maintenance.php` Two pre-aggregated summary tables accelerate dashboard and report queries: - `etl_gl_summary` — monthly GL totals per account, fed by every GL post/delete. Used by the accounting dashboard. - `etl_stock_summary` — monthly stock in/out totals per warehouse/product, fed by `WarehouseManager::adjustBalance()`. Used by the WMS dashboard and stock overview. Each summary table is maintained write-through on every transaction. The maintenance system provides a safety net for periods that drift out of sync due to crashes, rollbacks, or manual DB edits. **Gap detection** compares `MAX(source_updated_at)` in the raw source table against the summary table's `source_updated_at` per period. A mismatch means the summary is stale and needs repair. **Automatic repair** runs via the Node.js cron scheduler once per hour. Companies are spread across 24 hourly slots using `company_id % 24` to distribute load. GL runs at `:00` and stock runs at `:30` past each hour. **Manual rebuild** is available in the maintenance UI. The page shows the cron schedule slot, last run result, and a live count of current gaps. A full rebuild drops and regenerates all periods for the company. Backend support: - `EtlManager` — GL ETL (gap detection, period repair, full rebuild, status) - `EtlStockManager` — Stock ETL (same interface, works across dynamic `td_stock_` tables) ## Node.js Cron Scheduler File: - `nodejs/scheduler.js` The scheduler runs inside the Node.js process alongside the Socket.IO server. It uses `node-cron` to call PHP cron endpoints over HTTP on a fixed schedule. The shared `x-cron-secret` header authenticates each call. Current schedules: | Schedule | Endpoint | Purpose | |---|---|---| | `0 * * * *` (every hour, `:00`) | `/cron/etl_gl_maintenance.php` | GL summary gap repair for slot = current hour | | `30 * * * *` (every hour, `:30`) | `/cron/etl_stock_maintenance.php` | Stock summary gap repair for slot = current hour | Each cron run processes only the companies whose `company_id % 24` equals the current hour slot — no company is processed more than once per hour. ## Database Schema Setup Files: - `setup.php` The auth database includes a `schema_migrations` table, but this repository snapshot does not contain a `migrations/` directory or `migrate.php`. Fresh installation schema creation is currently handled by the CLI-only `setup.php` script, with some runtime-created structures such as dynamic `td_stock_` tables. ## File Uploads File: - `app/assets/utils/classes/FileUploader.php` File upload support is used by product/contact/company/profile flows. It handles directory creation, uploaded file lists, cleanup of replaced files, and rollback on failure.