# BMS v2 — single-branch local/cloud pilot

## Included behavior

The operational branch/warehouse runs on a Windows WAMP server over the LAN. Existing sales, purchasing, inventory, cash, staff and accounting workflows remain authoritative locally. Internet loss does not block them. The management office has a separate cloud login, reports, CSV exports, last-contact/lag warnings, audit review and approved control requests. Multi-branch remains disabled. Head Office holds no independent stock or sales sequence.

Sales numbers use an atomic sequence starting at 1 for empty v2 books; existing printed numbers are preserved and subsequent numbers advance above the current maximum. Purchase bills and receipts retain their independent, immutable database numbers. Internal row UUIDs and revisions are stored in v2_entities; company, branch and node UUIDs are in v2_runtime. Terminals share the local server rather than creating disconnected databases; transaction ownership remains in the existing user/audit records.

Transactional database triggers capture supported operational and accounting tables, including stock counts and purchase evidence. BmsV2PDO assigns a UUID to each application transaction. A serialized InnoDB counter ensures committed changes have a gap-free order; rollback removes rows, identity revisions and queue entries together. The cloud keeper stores projections, never re-posts money or journals, and commits complete business transactions before acknowledgement. Authenticated event identity, canonical hashes and entity revisions prevent duplicate or conflicting replay. Passwords, login attempts, tokens and password hashes are excluded. Initial-snapshot and current-source watermarks distinguish a complete replica from a partially uploaded one.

Management owners approve or reject pending requests. Managers can propose financial-master changes, viewers can read only. Supported controls are customer credit ceilings, supplier floors, product sale/cost rates, reorder levels, and owner-approved branch-user activation. Commands expire after 24 hours, check the expected source revision and apply with a durable command receipt plus local audit. The last active branch owner cannot be disabled. These controls do not replace local invoice validation. Each company has one paired operational node in this release.

Purchase bills accept JPG, PNG, WebP and PDF files before saving (queued in the page) and after saving. Uploads are linked only after a purchase exists. MIME/content, size and SHA-256 are verified; up to ten current files of 8 MiB each are allowed. Replacement preserves history. Files are stored in the database, included in database backups and replicated with metadata. Management can review/download them after sync. Unsaved queued files remain only in the current page and are covered by navigation warnings.

## Install or upgrade the branch

1. Preserve a private file backup and a consistent database backup with routines and triggers. Pause operational writes for the maintenance installer. Do not import schema.sql into existing books.
2. Deploy the source to a separate test folder and a separately configured database. For a new empty test company only, follow README.md baseline import/bootstrap instructions first.
3. Run `php bin/v2-install.php --isolated-test` only for a database named bms_v2_local_* or bms_v2_qa_*. For an existing authorized installation use BMS_V2_MAINTENANCE=1 after backup and stopping writes, then run `php bin/v2-install.php`. The installer is additive, assigns UUIDs, creates triggers and snapshots supported rows. If interrupted, rerun in maintenance mode; captured rows are not duplicated. Snapshot readiness is marked only after completion.
4. Copy v2-config.example.php to untracked v2-config.php, set mode branch, an HTTPS cloud endpoint and a unique random token of at least 32 characters. Never put credentials into a repository. Run `php bin/v2-pair.php` to create protected private/v2-pairing.json.
5. Run `php bin/v2-sync.php` periodically. It sends one whole transaction per request, bounds runtime, retains failures, persists exponential retry/backoff (maximum 15 minutes) and prevents overlapping workers. --force bypasses only the retry delay. A transaction over 32 MiB stops delivery visibly; it is never silently split or dropped.
6. On Windows run bin/install-v2-task.ps1 with the PHP path to register a hidden one-minute task for the signed-in user. For unattended branch-server operation, configure an appropriate service account in Task Scheduler. On Linux, run the same CLI command through cron. Transport is outbound; no inbound branch firewall opening is needed.

Open v2-console.html while signed in at the branch for queue count and last error/contact. Existing permissions, session timeouts and last-owner controls remain. Platform-company membership grace dates are enforced from local records; no new internet licence call is required. The isolated legacy test company has no subscription expiry. Remote revocation and commands take effect after reconnect; approval-dependent work remains pending while offline.

## Namecheap cloud keeper

Suggested hostname: bms-cloud.readysols.com. Create a separate subdomain document root, database and database user; verify availability, HTTPS, PHP/extensions, request limits and storage allowances first. Do not copy over readysols.com or an accounting subdomain. No hosting or DNS change is part of the local pilot.

Build a source-only archive using `python bin/package-v2.py <output.zip>`. It excludes branch posting endpoints, business rows, configuration and pairing tokens. Upload to the new document root only. Configure v2-config.php with mode cloud, cloud_database credentials and allow_local_http=false. A private configuration outside the document root can be selected through BMS_V2_CONFIG if the host supports it. The supplied .htaccess blocks configuration, SQL, bin and private files; verify those protections on the host.

Run `php bin/v2-cloud-setup.php <private-pairing-file>` using cPanel Terminal/SSH or a one-time protected CLI job, with BMS_V2_MANAGEMENT_PASSWORD supplied privately. Setup refuses a nonempty database. Transfer pairing data securely and keep it outside the web root. Setup creates a separate cloud owner and stores only the node token hash. Management passwords are not copied from the branch. Additional scoped owners/managers/viewers can be created with bin/v2-management-user.php and a private environment password.

The cloud uses ordinary PHP requests and MySQL; no daemon, WebSocket process or cloud cron is needed. Branch scheduling drives delivery. Recommended limits: upload_max_filesize >=8M, post_max_size >=40M, memory_limit >=256M, MySQL max_allowed_packet >=32M. Required cloud extensions: pdo_mysql, JSON, fileinfo and session; branch transport also needs curl. The baseline needs its existing PHP extensions. Tested locally with PHP 8.3.6 and MySQL 8.3; shared-host configuration still needs verification.

## Reconciliation, restore and release limits

bin/v2-reconcile.php compares supported tables and rows against a locally accessible cloud database configuration after the queue drains. Keep that configuration private. Restore tests replay retained branch history into a keeper restored to an earlier cursor. No queued history is automatically purged. If cloud is ahead of a restored branch, delivery stops; restore matching backups and reconcile. Back up both databases, identities, routines/triggers and private configuration. Cloud recovery does not replace authoritative branch backups.

Operational writes must use the application or an approved maintenance procedure. Direct SQL imports, TRUNCATE, primary-key rewrites, schema changes and foreign-key cascade deletes are outside automatic-capture guarantees. Keep unsupported maintenance offline and rebuild/reconcile through a reviewed migration. Existing posted-journal immutability and accounting controls remain active.

The pilot covers the agreed single operational branch and management controls. Advanced invoice approval rules, remote journal/expense authoring, independent offline terminal databases and multi-branch consolidation are not enabled. Optional module enhancement ideas in the specification remain a roadmap. Namecheap publication and a real two-office acceptance run are deployment gates.

Original pending attachment files remain untouched in the earlier checkout. V2 evidence is implemented independently in purchase_evidence; do not install both implementations into one tenant without a reviewed migration. PR #11 includes earlier committed BMS enhancements because main predates the deployed baseline; review inherited commits before merging.

## Dashboard charts

Selected month, last 30 calendar days (including today) and full year are available in both dashboards. Net sales reconcile after commission and discounts; product quantities retain their units. Cash flow sums posted cash and bank movements with internal transfers cancelling and opening/cutover entries excluded. Expense charts show expense vouchers; payroll and cost of stock remain separate accounting reports. Customer/supplier panels show current balances, not historical balances for the selected sales period. Drawings are combined because existing records do not identify individual partners. All charts are read-only; no schema migration is required.
