OpenTrail
An open-source hiking platform and the most complete example of product, security, data, and release engineering in this journey.
Project identity
OpenTrail is an open-source community hiking platform built around free trail knowledge, minimal tracking, open data, offline access, and community contribution. The repository history begins July 18, 2026 with a monorepo, PostGIS schema, NestJS API, and Next.js/MapLibre web MVP.
The project charter is the source of truth for principles, planned features, deliberate deviations, and feature status. A separate future roadmap records post-1.0.1 work.
Shipped capabilities
Explore and understand trails
- Oregon-wide OpenStreetMap trail import with idempotent upserts and stitched hiking relations.
- Map-driven viewport and radius search, state filters, trail-name matching, and server-side location geocoding.
- PostGIS geometry, full-text/trigram search, real elevation gain from terrain data, and connecting-trail discovery.
- Parking, lodging, cabins, camps, parks, difficulty indicators, and route geometry.
Context, community, and safety
- Weather forecasts and active alerts through a server-side National Weather Service integration.
- Live wildfire information and proximity warnings.
- Guest and account-based saved trails.
- Moderated reviews and photos, user administration, bans, and role-aware moderation.
- Email directions composed in the user's mail client without server-side mailbox access.
Architecture and stack
OpenTrail is a modular npm workspace. Deployable applications live separately from shared packages and infrastructure code.
Geospatial data and performance
OpenTrail uses spatial database features rather than treating maps as decoration. Bounding-box and radius queries run against PostGIS. Map views snap to a zoom-aware cache grid so nearby pans reuse results, while responses are trimmed to the exact requested viewport.
- OSM imports preserve open-data attribution and can be rerun safely.
- Elevation is backfilled from digital elevation model tiles.
- Parking and lodging use distance-based spatial relationships.
- Search combines exact/partial trail names, full text, trigram similarity, and location geocoding.
- Administrative cache metrics show hit rate and frequently viewed areas without making cache behavior invisible.
Accounts, sessions, and privacy
The implementation deliberately chose revocable opaque sessions rather than JWT access tokens for the current phase. Passwords use Argon2id at the documented OWASP baseline. Session tokens are 256-bit random values in HttpOnly cookies; only their SHA-256 hashes are stored, allowing immediate revocation.
- Browsing does not require an account.
- Guest saved trails survive signup or merge into an existing account at login.
- Authentication routes have stricter throttling than general API routes.
- Unknown-email and wrong-password attempts return indistinguishable behavior, including a dummy-hash verification path.
- Secure-cookie mode is enabled when the application operates behind HTTPS.
- Server-side geocoding prevents the user's address-search request from going directly to the external provider.
Moderation, media, and user safety
Reviews and photos are private to the moderation workflow until approved. Uploaded images are decoded and re-encoded to WebP while EXIF and GPS metadata are removed. Only approved media becomes public or can serve as a trail cover.
Administrators and moderators manage queues. A user ban requires a reason, revokes sessions, prevents login, and removes the user's public contributions in one transaction. Unbanning restores account access without silently republishing removed content.
Docker, permissions, backup, and recovery
The Compose stack contains PostgreSQL, a one-shot migration job, MinIO, API, Redis, and web services. Multi-stage images and health checks make startup order and runtime state visible.
Least-privilege database roles
- A schema owner performs migrations.
- The API runtime account receives table CRUD without DDL.
- A separate human administration role supports controlled maintenance.
- Strong credentials are generated into ignored configuration.
Recovery design
- Database dumps preserve PostGIS application data.
- Object storage requires its own backup and restore process.
- Migrations are applied before application health is trusted.
- Restoration is verified through health checks and a real trail journey.
Versioning, releases, and verification
The root and deployable packages share the working version. Release tags, CHANGELOG, CODE_CHANGELOG, HOTFIXES, release documents, smoke scripts, version checks, and domain-specific validation scripts create layered evidence.
Hurdles and deliberate decisions
- Trail data import moved earlier because an empty map cannot validate the product.
- The API remains a deployable application, while packages are reserved for shared libraries.
- Kubernetes and Terraform were deferred until deployment complexity justified them.
- Moderation is currently a module rather than a separate service.
- Opaque sessions replaced an earlier JWT idea to make revocation immediate.
- Google imagery was avoided because its licensing is incompatible with the platform's open-data goals.
- Redis is provisioned ahead of full background-job use, so unused complexity must remain visible.
Roadmap and future planning
The roadmap sequences bike access and suitability, live GPS progress, offline trail packs, wildlife sightings, OAuth, trust/reputation, condition reports, GPX uploads, mobile work, contributor onboarding, and a public beta. Each phase is evaluated against privacy, data licensing, offline behavior, operational cost, and whether the web MVP is stable enough to support expansion.
Future features are documented as planned until implementation, verification, and release evidence prove they are shipped.