Development guide¶
Setup¶
Use an isolated Linux VM when changing workers, systemd, filesystem permissions, or publishing. A PHP built-in server can support limited UI work, but it does not reproduce Apache prepending, systemd, FIFO, or service mount behavior.
- Create a disposable PostgreSQL/PostGIS database and apply
installer/setup.sqlonce. - Create a secret-free
admin/incl/const.phpmatching configuration.md. - Select
localauth only for isolated development, or provide a development Central instance. - Install PHP 8.1+ with extensions: pgsql, curl, yaml, zip, gd, ssh2, and sodium when testing secret helpers.
- Install worker dependencies only for the project types under test.
Do not develop against the checked-in credentials. Generated INI/YAML and rsync scripts contain plaintext passwords; keep the entire environment disposable.
Coding model¶
- Pages live under
admin/; mutations generally live underadmin/action/. - Shared auth should enter through
incl/geosync_auth_prepend.php. - Domain classes in
admin/class/accept a PostgreSQL connection and often owner/sharing context. - SQL uses the procedural
pgsqlAPI. Preferpg_query_paramsfor new code; much legacy SQL is string-built and should not be copied. - UI actions typically return
{success, message}JSON. - Worker settings are persisted by
daemon_Classinto<id>.inior<id>.yaml. - Service operations must go through the backend FIFO, not direct web-server
systemctlexecution.
Tests¶
There is no first-party automated test suite or test command. Files under vendor/**/tests test vendored dependencies and are not GeoSync tests; mtest.php is an ad-hoc script, not a harness.
Minimum change verification:
Then exercise on a disposable integration host:
- unauthenticated, authenticated non-admin, and admin requests;
- ownership checks and invalid IDs;
- create/update/delete and generated config content;
- FIFO command and systemd status;
- first sync, update sync,
single_run, and destructiveforce_init; - unavailable remote/PostgreSQL/upstream behavior;
- logs and filesystem permissions.
For new code, introduce focused unit/integration tests with an explicit runner rather than treating manual QA as sufficient. No coverage threshold is currently defined.
Debugging¶
- Enable PHP error logging in development, but never display errors or connection strings in production.
- Inspect Apache/PHP logs,
journalctl -u qz-sync-backend,journalctl -u '<type>-sync@<id>',/var/log/qz_sync_backend.log, and/var/log/qz_sync<id>.log. - Compare
admin/incl/const.php,/etc/default/qz-sync-backend, service unit paths, and generated project files. - Run a worker as user
quartzwith one project ID only after redacting output and backing up data. - Query metadata and target PostGIS independently to distinguish control-plane from worker failures.
- For proxy failures, verify the exact method/path allow-list and upstream ports. The checked-in analysis unit port does not match the PHP default.
Add an admin endpoint¶
- Add an action under
admin/action/and requireincl/geosync_auth_prepend.phpbefore application work. - Start/ensure the session and require constants/classes.
- Enforce the required legacy access level and record ownership; Central mode currently maps authorized platform admins to that session.
- Validate method and all input. Use parameterized SQL and fixed allow-lists for identifiers/operations.
- Return a deliberate status code, content type, and stable JSON shape.
- Add the UI caller and integration checks.
If adding a path proxied by api/proxy.php, add it under the exact service and HTTP method in $allowed; unknown service/path combinations are intentionally rejected. Decide whether PHP handles it locally or forwards it, do not pass untrusted arbitrary upstream URLs, and update api.md plus openapi.yaml.
Add a database table¶
- Add an idempotent numbered SQL migration; do not edit only
installer/setup.sql. - Update
installer/setup.sqlso new installations reach the same final schema. - Specify ownership, foreign keys, delete behavior, uniqueness, defaults, and indexes.
- Use a transaction where PostgreSQL permits it and provide a backup/rollback plan.
- Update classes/actions with parameterized queries and ownership checks.
- Test both clean install and upgrade from the previous schema.
There is no migration runner or schema-version table. Operators must apply migrations explicitly and record completion. The current sync_secrets class is incomplete because no DDL is supplied; add migration/setup DDL before using it.
Worker changes¶
Keep installer/ copies and usr-local-bin/ copies synchronized where both exist. Verify current deploy/ units and installer service templates. Preserve graceful SIGTERM behavior and avoid logging credentials. Any change to generated config keys must update project creation, daemon editing, workers, and this documentation.
Release process¶
No automated release workflow, version file, artifact build, or tags exist. Use this baseline process:
- Freeze scope and update changelog.md under an
Unreleasedsection. - Run PHP syntax checks and the manual integration matrix for all affected project types/auth modes.
- Validate clean schema plus every migration on backups or disposable databases.
- Review generated files and repository history for secrets; rotate any exposure.
- Confirm service units, external dependency versions, and rollback/backup steps.
- Move changelog entries to a dated semantic version, create an annotated tag, and publish deployment notes/artifacts through the organization’s approved process.
1.0.0 in the changelog is a documentation baseline because the repository has no tags; it is not evidence of a previously shipped artifact.