This page preserves the technical repository notes that previously lived in
../README.md. Keep the root README focused as the project landing page.
Link planning web application for terrain-aware radio path analysis.
Inspired by Radio Mobile by Roger Coude (VE2DBE).
- License: GNU GPL v3.0 (LICENSE)
- Security policy: SECURITY.md
- Privacy notice: docs/legal/PRIVACY.md
- Terms and acceptable use: docs/legal/TERMS.md
- Sensitive data warning: do not store secrets in app content; visibility levels are collaboration controls, not a secret vault.
- Legal credits/notices:
The project is operated in three stages:
- Local dev (primary iteration environment)
- Staging (cloud validation)
- Production (live)
Operational rule:
- Changes are built and tested locally first.
- Then deployed to staging.
- Then promoted to production.
Install dependencies:
npm installRun local edge-parity stack:
docker compose up --build edgeOpen:
http://localhost:8788
Other local runtime options (legacy/optional):
npm run dev
npm run dev:edge
docker compose up --build web
docker compose up --build devDefault ports:
edge:http://localhost:8788web:http://localhost:8080dev:http://localhost:5173
Core commands:
npm run build
npm test
npm run test:ciAdditional smoke scripts:
npm run smoke:edge
npm run smoke:scenario
npm run smoke:profile
npm run smoke:fit-profile
npm run smoke:itm/api/v1/calculate runs directly in LinkSim Pages Functions and uses the same propagation stack as the app (ITM with Copernicus terrain sampling).
Behavior notes:
- Public endpoint:
https://linksim.link/api/v1/calculate - Terrain source: Copernicus DEM via
/copernicus/30m/* - If node ground elevation is omitted, the API samples terrain and uses that elevation with
2mdefault antenna height - Result includes app-style pass/fail text, for example
LOS clear + fail at 83.39 km (-133.6 dBm after env loss) - Edge rate limit:
CALC_API_PROXY_RATE_LIMIT_PER_MINUTE(default120)
Example request:
curl -X POST http://localhost:8788/api/v1/calculate \
-H 'content-type: application/json' \
-d '{
"calculation": "link_budget",
"input": {
"from_site": "Site A",
"to_site": "Site B",
"frequency_mhz": 868,
"rx_target_dbm": -110,
"nodes": [
{"name": "Site A", "lat": 59.9139, "lon": 10.7522},
{"name": "Site B", "lat": 59.9170, "lon": 10.7600}
]
}
}'Use docs/release-flow.md as the source of truth for
deployment and release operations. Normal staging and production deploys run
from CI after PRs merge to staging or main; do not run deploy scripts
locally for the standard release flow.
Production deploys are guarded and require:
HEADis taggedv<package.json version>- Version is bumped in
HEADcompared toHEAD^
Build label rules:
- Local:
vX.Y.Z-alpha+<commit> - Staging:
vX.Y.Z-beta+<commit> - Production:
vX.Y.Z - Same commit always keeps the same base version (
X.Y.Z) across all environments.
This repo uses:
- Cloudflare Pages + Functions
- D1 for application data
- R2 for avatar images
- Cloudflare Access for authentication boundary
Primary configs:
- Production: wrangler.toml
- Staging: wrangler.staging.toml
Optional basemap provider environment variables (admin-configured only):
VITE_MAPTILER_KEYVITE_STADIA_KEYVITE_KARTVERKET_API_KEYVITE_KARTVERKET_WMTS_BASE_URL(optional override)VITE_KARTVERKET_TILE_TEMPLATE(optional explicit template; overrides base URL)
Detailed setup docs:
Refresh staging from production snapshots:
npm run refresh:stagingOr run separately:
npm run refresh:staging:d1
npm run refresh:staging:r2- Terrain data is fetched on demand and cached client-side.
- API proxies and geocode endpoints include method/rate-limit safeguards.
- In local runtimes without edge functions, some cloud behaviors are emulated/fallback.
- Basemap provider failures auto-fallback to CARTO with a non-blocking warning.
src/: frontend appfunctions/: Cloudflare Pages Functions APIdb/: SQL schema and migration assetsscripts/: deploy/release/smoke toolingconfig/: TS/Vite/Vitest configsdocs/: setup, legal, testing, and operations documentationpublic/: static assetsnginx/: nginx config used by Docker flows
- Keep working tree clean before deploy commands, except expected generated build metadata in
.tmp/buildInfo.ts. - Follow docs/release-flow.md for production promotion.
- When changing auth/permissions, add or update tests in the same pass.