Application updates
Q-Putaway has two independent update paths.
1. Browser / PWA update (automatic)
When new static files are deployed, the service worker detects a new version and shows "A new version is available". Users choose Update now (warned first if a form has unsaved changes, and blocked while an operation is running) or Later. Only the screens and scripts in the browser are refreshed; obsolete caches are deleted. This never updates PHP files on the server.
2. Server update (Super Admin)
Administration → Updates shows the current version and schema version, the update history, and an optional "check for updates" (when updates.feed_url is configured; it never installs automatically).
Package format
A .zip containing:
manifest.json:{version, min_version, notes, files: [{path, sha256}]}manifest.sig: a base64 Ed25519 detached signature ofmanifest.json- the files themselves
Applying
- Upload the package. Q-Putaway verifies the signature against
updates.public_keyinconfig/config.php, verifies every file hash and checks compatibility (min_version≤ current <version). - It refuses unsafe paths (
.., absolute paths, backslashes, null bytes, dotfiles,config/,storage/), so configuration, uploads, backups and credentials are never overwritten. - The package is staged in
storage/updates/staging/. - Apply (with password confirmation) first creates a database backup and a rollback archive of every file that will be replaced, then copies the files and runs pending migrations. The result is recorded in the update history and the audit log.
- Rollback restores the files from the rollback archive. Database changes from migrations need the pre-update backup to be restored.
Updates stay disabled until a public key is configured.
For the vendor: signing packages
php tools/keygen.php /secure/place/qputaway-update.key # prints the public key → put it in config/config.php updates.public_key
php tools/build_update.php --key=/secure/place/qputaway-update.key --version=1.0.1 --min=1.0.0 --notes="Fixes" file1 file2 …
# or build from a git range: --git=v1.0.0..HEAD
Keep the private key offline. Bump app/version.php (QP_VERSION, and QP_SCHEMA_VERSION when migrations are added) in every release.