The Problem
Travel planning tools are either fragmented SaaS services or static check‑lists that cannot be edited collaboratively in real time. Teams that need on‑premise control—travel agencies, corporate travel desks, or privacy‑concerned families—must stitch together separate maps, budgets, and itinerary editors, each with its own data store and auth layer.
What This Does
The TREK repo delivers a self‑hosted, full‑stack travel planner. It bundles four independent projects:
- shared – 1 117 files (i18n types, helpers, UI primitives) that are imported across client and server.
- client – a React + Vite SPA (
client/src/App.tsx) with Tailwind UI, offline‑first PWA support, and end‑to‑end tests underclient/e2e/. - server – an Express‑style NestJS API (
server/src/nest/app.module.ts) handling auth, DB access, and real‑time sync. - plugin‑sdk – a small extensibility surface (
plugin-sdk/src/index.ts) for third‑party plugins.
Together they provide drag‑and‑drop day planning, interactive maps, budgets, packing lists, a journal, and an AI‑powered assistant, all behind SSO and stored in a PostgreSQL container.
How It Is Wired
Execution starts when Docker Compose launches the client and server containers defined in docker‑compose.yml.
- Browser → client –
client/index.htmlloads the Vite bundle; the root React component inclient/src/App.tsxmounts the router and i18n (client/src/i18n/index.ts). - Client → server – API calls go to Nest’s HTTP layer (
server/src/nest/app.module.ts). This module imports 45 other Nest modules (high instability 0.96) and wires controllers, services, and guards such asjwt-auth.guard.ts(used by 32 modules). - Server → shared – Core types like
shared/src/i18n/types.tsare imported by 707 modules, making it the largest hub; any change propagates widely. - Server → DB –
server/src/db/database.tscreates the TypeORM connection and is referenced by 44 modules (part of a circular import withairportService.ts). - Real‑time sync – WebSocket gateways in
server/src/nestbroadcast updates that the React UI consumes via hooks inclient/src/components.
The import graph contains 1 500 internal modules and only two circular dependencies, but the hub modules (shared/src/i18n/types.ts, server/src/db/database.ts) carry the biggest blast radius for refactoring.
How To Use It
# Clone the repo
git clone https://github.com/moses-y/TREK
cd TREK
# Build and start all services
docker compose up --build -d
- The
Dockerfilebuilds the Node runtime (node:24-alpine) for both client and server. - Environment variables required by Nest (e.g.,
DATABASE_URL) are read at container start; they are documented inserver/README.md(not shown here). - After containers are healthy, open
http://localhost:3000to reach the SPA. - Run the test suite locally with
npm testinsideclient/orserver/; CI currently does not invoke these tests (see health issues).
Real‑World Use
A corporate travel desk can deploy TREK behind its VPN, connect the API to an internal PostgreSQL, and enable SSO via Azure AD. Employees create itineraries in the React UI; the server persists each day plan, broadcasts changes over WebSocket, and the UI updates instantly for all participants. Plugins added through plugin-sdk can inject custom cost‑center validation without touching core code.
Code Health & Issues
- HIGH – Pin GitHub Action versions to commit SHAs (
.github/workflows/*). - HIGH – CI never runs the test suite; add a
npm teststep. - HIGH –
continue-on-errorinlint-prettier.ymlmasks failures. - HIGH – Docker workflow pushes directly to
main; switch to PR‑based deployment. - HIGH –
plugin-sdk/src/index.tsusesevalon runtime data. - MEDIUM – No Dependabot/Renovate config.
- MEDIUM – Base images in
Dockerfileare unpinned; use digests. - MEDIUM – No dependency‑vulnerability scan in CI.
- MEDIUM – Large binaries (
admin1.geojson.gz,DayItineraryRemovePlaceByButton.gif) should be stored via LFS or external storage. - MEDIUM – Checkout step keeps credentials; set
persist-credentials: false. - MEDIUM – Empty
catch {}blocks inserver/src/db/database.tsandserver/src/demo/demo-reset.ts. - MEDIUM – Import cycles involving
server/src/db/database.tsandserver/src/services/airportService.ts. - MEDIUM – Duplicated i18n help blocks across 44 language files.
- MEDIUM – High branching density in several helper modules; consider refactoring.
- MEDIUM – Deep nesting (depth 7) in
client/src/components/OAuth/ScopeGroupPicker.tsx.
All findings are derived from static analysis; no additional issues were observed.
The Bottom Line
TREK offers a complete, on‑premise travel‑planning stack with modern React UI and NestJS backend, ready for container deployment. The codebase is sizable but well‑structured; however, hub modules and a few architectural smells (import cycles, duplicated i18n) make large‑scale changes risky. CI gaps and security‑hardening items should be addressed before production use. Suitable for teams that need full data control and are comfortable maintaining Docker‑based Node services.