Development¶
Repository layout¶
cmd/server/: main HTTP process and route registration.internal/api/: HTTP handlers, proxies, ACL checks, and orchestration.internal/publish/: project install/update, manifests, forms, legends, and runtime metadata.internal/runtimedataset/: GeoPackage/PostGIS import and registry.internal/{authstore,basemap,browsermap,ingest,metadata,versions}/: persistence and domain stores.internal/{forms,expr,postgislayer,pgservice,gdalinfo}/: QGIS parsing and external-tool adapters.html/qgis-publish/: browser application.qcarta-tiles/: independently built tile/WMS cache.deploy/andqcarta-tiles/deploy/: systemd/environment samples.../shared/authand../shared/ui: local replaced modules imported by the main service.
Do not run the main module outside the sibling repository layout unless go.mod's local replace is deliberately changed.
Build and test¶
The two modules have different Go directives: 1.23 for the main service and 1.25 for qcarta.
The test suite covers QGIS XML/forms/relations, project manifests and updates, WMS filter/query preservation, PostGIS datasource parsing, report validation, metadata/browser-map validation, runtime rewrite/import helpers, tile caching, metatiles, singleflight, and safe mode. Most tests use temporary files and in-process HTTP recorders.
internal/api/feature_relations_scan_test.go reads TEST_POSTGRES_URL; without it, the database-dependent test is expected to skip. Full integration behavior additionally requires QGIS Server, GDAL/OGR, PyQGIS, Central PostgreSQL, PostGIS, GeoVault, qcarta, and OSRM.
No CI workflow is present, so repository automation does not verify these commands.
Running¶
For a realistic local stack, configure Central PostgreSQL and run QGIS Server and qcarta separately. Keep mutable roots outside source control. Use redacted local secrets; never copy credential-like values from tracked samples.
Source conventions¶
- Go code uses standard-library HTTP routing and
log.Printf. - Database SQL is embedded in store/schema packages.
- Project state is represented by
.qgis-publish.json; preserve backward-compatible fields when changing it. - QGIS query forwarding deliberately preserves raw encoded filter segments. Avoid normalizing an entire query through
url.Values.Encode()without reviewing filter tests. - File and project identifiers are validated to prevent traversal; retain containment checks for new file routes.
pg_service.confwrites are atomic but include plaintext credentials.
Adding database changes¶
Current startup schema is idempotent DDL, not a migration system. Additive IF NOT EXISTS changes are consistent with the implementation, but changed constraints/types need an explicit migration strategy before deployment. Update Database, tests, and failure behavior together.
Adding environment variables¶
Define a single source default and document:
- whether empty means disabled, inherited, or invalid;
- accepted formats and range handling;
- whether the variable contains a secret;
- which process reads it;
- filesystem/network prerequisites.
Update Configuration and deployment samples without committing real credentials.
Manual integration checks¶
- Start the main service and confirm
/api/discoveryunder the configured base path. - Confirm auth-disabled/enabled startup behavior in logs.
- Upload a small QGIS project and verify manifest/resource creation.
- Request WMS capabilities through
/qgis/{projectId}. - Start qcarta and check
/api/health, a tile miss, then a hit. - If enabled, import a disposable GeoPackage into a disposable PostgreSQL cluster.
- Restart both processes to verify filesystem persistence and the intentionally non-durable job state.
Documentation maintenance¶
Keep these documents source-verified. Clearly label generic operational recommendations, because the repository does not include Docker/Compose, web-server virtual hosts, TLS, CI, packaging, or release automation.