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 assrc/server/db/schema/vehicle.tsandsrc/server/db/schema/audit.tsexpose 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.tscontain high‑branching decision trees (17 branches in 53 lines). UI components call these services through thin wrappers insrc/lib/services/(e.g.,entity-service.ts).
- State flow – UI components use Svelte stores exported from
src/lib/components/app/StoreResourceState.svelteand invoke server endpoints via fetch calls generated by SvelteKit.
- Blast radius – The most connected modules are
src/server/db/index.ts(12 fan‑in) andsrc/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/*.ymluses tag references (e.g.,pnpm/action-setup@v4). Replace with commit SHAs. - High – Push to default branch –
docker-publish.ymlpushes directly tomain. Change to a bot branch and open a PR. - Medium – Least‑privilege GITHUB_TOKEN –
ci.ymldeclares no permissions; addpermissions: 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 tonode:22-alpine@sha256:<digest>. - Medium – No dependency scan – CI lacks a vulnerability review step; add
dependency-review-actionorosv-scanner. - Medium – Checkout persists token – Set
persist-credentials: falseon 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.