The Problem

Organizations that manage fleets need a single place to record fuel purchases, maintenance work, insurance, and pollution certificates. Existing spreadsheets or ad‑hoc tools make it hard to enforce data quality, generate alerts for upcoming renewals, and produce usage analytics.

What This Does

Tracktor is a SvelteKit web app that stores vehicle‑related records in an SQLite database using Drizzle ORM. The UI lives under src/lib/components/ (e.g., src/lib/components/feature/fuel/FuelLogForm.svelte, src/lib/components/feature/vehicle/VehicleCard.svelte). Server‑side routes and data services are in src/server/ (e.g., src/server/db/index.ts, src/server/services/configService.ts). The top‑level entry points for the component library are the index.ts files in src/lib/components/app/ and src/lib/components/ui/ (accordion, alert, badge, button). The Dockerfile builds a container that runs the SvelteKit server, and CI is driven by GitHub Actions (.github/workflows/ci.yml, docker-publish.yml).

How It Is Wired

Execution starts when the SvelteKit server is launched (via pnpm run dev locally or the Docker CMD). The first request hits a generated route in src/routes/ (not listed but implied by SvelteKit) which imports the UI entry point src/lib/components/app/index.ts. That module re‑exports the core UI components and pulls in the domain layer src/lib/domain/index.ts.

  • Database access – All persistence goes through src/server/db/index.ts, which aggregates 12 downstream imports (the measured “Hub module” finding). Individual schema files such as src/server/db/schema/vehicle.ts and src/server/db/schema/audit.ts expose Drizzle table definitions. Service code (e.g., src/server/services/configService.ts) reads/writes via these schemas.
  • Business logic – Services like src/server/services/notification-provider-service.helper.ts contain high‑branching decision trees (17 branches in 53 lines). UI components call these services through thin wrappers in src/lib/services/ (e.g., entity-service.ts).
  • State flow – UI components use Svelte stores exported from src/lib/components/app/StoreResourceState.svelte and invoke server endpoints via fetch calls generated by SvelteKit.
  • Blast radius – The most connected modules are src/server/db/index.ts (12 fan‑in) and src/lib/domain/index.ts (8 fan‑out, instability 1). Changing these files can affect many other modules, so keep them stable. No circular dependencies were detected.

How To Use It

# Clone the repo
git clone https://github.com/moses-y/tracktor
cd tracktor

# Install dependencies with pnpm (lockfile present)
pnpm install

# Run locally (SvelteKit dev server)
pnpm dev

For production, build and run the Docker image:

docker build -t tracktor .
docker run -p 3000:3000 tracktor

Configuration values are defined in .env.example; copy it to .env and adjust as described in docs/environment.md. The installation workflow is documented in docs/installation.md.

Real‑World Use

A logistics company could deploy Tracktor behind an internal reverse proxy, point the SQLite file to a persistent volume, and integrate the notification service with Gotify (src/lib/components/feature/settings/GotifyProviderForm.svelte) to push renewal alerts to drivers’ mobile devices.

Code Health & Issues

  • High – Pin GitHub Actions.github/workflows/*.yml uses tag references (e.g., pnpm/action-setup@v4). Replace with commit SHAs.
  • High – Push to default branchdocker-publish.yml pushes directly to main. Change to a bot branch and open a PR.
  • Medium – Least‑privilege GITHUB_TOKENci.yml declares no permissions; add permissions: contents: read.
  • Medium – Dependabot missing – No dependabot.yml; add one to keep dependencies patched.
  • Medium – Base image not pinned – Dockerfile uses node:22-alpine; switch to node:22-alpine@sha256:<digest>.
  • Medium – No dependency scan – CI lacks a vulnerability review step; add dependency-review-action or osv-scanner.
  • Medium – Checkout persists token – Set persist-credentials: false on the checkout step.
  • Medium – Run as root – Dockerfile lacks a non‑root USER; create an unprivileged user.
  • Medium – Test coverage – Only 2 test files for 465 source files (0.004 ratio). Prioritize tests for high‑fan‑in modules (src/server/db/index.ts, src/lib/domain/index.ts).
  • Low – Job timeouts – CI jobs have no timeout-minutes; add reasonable limits.

Additional measured findings: duplicated 6‑line code blocks across >115 files, deep nesting (max depth 6) in several UI and config files, and high branching density in chart utilities and notification helpers. Refactoring shared logic and flattening control flow will reduce cognitive load.

The Bottom Line

Tracktor delivers a functional SvelteKit‑based vehicle management UI with a clear separation between UI components and a modest SQLite backend. The codebase is sizable and contains duplicated UI snippets and a few architectural hotspots that increase change risk. It is suitable for teams comfortable extending SvelteKit and willing to invest in refactoring and stronger CI/CD hygiene before using it in production.