Skip to content
trakrfPublic

About

TrakRF RFID data collection and integration platform

Resources

Code of conduct

Contributing

Security policy

Stars

6 stars

Watchers

0 watching

Forks

Latest commit

 

History

3,198 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

# TrakRF Platform

RFID/BLE asset tracking platform for manufacturing and logistics.

## Architecture

**Stack:**
- Backend: Go
- Frontend: React
- Database: TimescaleDB
- MQTT: Integrated broker
- Deployment: Docker

**Structure:**

platform/ ├── backend/ # Go API server (placeholder) ├── frontend/ # React web app (@trakrf/frontend - handheld RFID app) ├── database/ │ └── migrations/ # Versioned SQL migrations (golang-migrate) ├── docs/ # Documentation │ └── frontend/ # Frontend docs (architecture, vendor specs) ├── marketing/ # Marketing website └── docker-compose.yml


**Frontend**: Full-featured React + TypeScript app for CS108 RFID handheld readers with Web Bluetooth integration, comprehensive test suite (Vitest + Playwright), and mock testing support. See [docs/frontend/](docs/frontend/) for architecture and vendor specs.

## Development

### Prerequisites
- Docker & Docker Compose
- Just (task runner) - https://just.systems/
- direnv (optional but recommended - auto-loads `.env.local`)

**Note:** Go and Node.js are NOT required for Docker-based development. Install them only if you want to run services natively.

### First step in any fresh checkout or worktree

```bash
just bootstrap

The backend embeds two generated, gitignored artifacts — backend/frontend/dist and the OpenAPI specs under backend/internal/handlers/swaggerspec/ — so a fresh tree does not compile until they exist. Without this step just validate fails with pattern frontend/dist: no matching files found, which names neither the missing step nor the fix.

just bootstrap installs workspace dependencies, builds the frontend and generates the specs. It is idempotent and near-instant once satisfied, so it is safe to re-run whenever; just bootstrap --force rebuilds regardless. It fails loudly and non-zero — if it did not, the next command to fail would be an unrelated-looking one.

Cold, it takes a couple of minutes and needs no supervision, so it is worth backgrounding at the start of a session rather than waiting on it.

Quick Start (Docker-First)

1. Configure environment

# Optional. Every value has a working local default, so the stack comes up on
# the canonical database with no env file at all — you need this only to set
# things that have no sensible default (MQTT credentials, a Resend key).
cp .env.local.example .env.local

# Enable direnv (auto-loads .env.local)
direnv allow

There is one local env file: .env.local. just bootstrap symlinks .env to it, because docker compose reads .env while direnv reads .env.local — as two real files they can name two different databases, and the shell environment silently outranks .env, so the disagreement does not even present the same way twice. That is not hypothetical: it is what TRA-1190 was filed for.

It holds parts, not connection URLs — PG_DATABASE, PG_APP_USER, PG_MIGRATE_USER and their passwords — and docker-compose and the justfiles assemble the DSNs from them. This mirrors what the cluster has done since the move to GKE/CNPG, where helm/trakrf-backend interpolates postgresql://$(PGUSER):$(PGPASSWORD)@host:port/db from a role name and a Secret rather than storing a URL. Nothing stores a DSN, so nothing can hold a stale one. just test-env-drift checks these against database/justfile, which is what actually declares the database and role names.

Database roles. The local stack mirrors what preview and prod run on: a trakrf database owned by trakrf-migrate (DDL), served by trakrf-app (CRUD only — not a superuser, no BYPASSRLS, owns nothing). just database up creates both. This is deliberate: a superuser bypasses row-level security, so connecting as postgres means no policy is ever evaluated locally and a missing WithOrgTx looks healthy until it reaches a deployed environment. If you hit a permission error, that is the signal working — don't put postgres back in PG_APP_USER. See database/sql/ and ADR 0003.

2. Start full stack

# Start database + backend with hot-reload
# This will:
#   1. Start TimescaleDB and bootstrap the trakrf database + roles
#   2. Run database migrations automatically (as trakrf-migrate)
#   3. Start backend with Air hot-reload (as trakrf-app)
just dev

# Backend will be available at http://localhost:8080
# Logs are streaming to terminal

# In another terminal, test endpoints:
curl localhost:8080/healthz   # Liveness check
curl localhost:8080/readyz    # Readiness check
curl localhost:8080/health    # Detailed health (JSON)

3. Develop with hot-reload

# Edit backend/main.go or backend/health.go
# Air automatically rebuilds and restarts (< 5 seconds)

# View logs
just dev-logs

4. Stop services

# Stop all services
just dev-stop

# Or stop database
just database down    # New delegation syntax
just db down          # Lazy alias (same result)

Development Workflow

This project uses Just's delegation pattern for monorepo task management.

From project root (delegation syntax):

# Full stack
just dev           # Docker-based (db + backend container + migrations)

# Workspace-specific (delegation)
just frontend dev        # Start Vite dev server
just backend dev         # Start Go server locally
just frontend typecheck  # TypeScript type checking
just backend test        # Run Go tests

# Lazy dev aliases (shorter syntax)
just fe dev        # Same as: just frontend dev
just be test       # Same as: just backend test
just db up         # Same as: just database up

# Combined validation
just lint        # Lint both workspaces
just test        # Test both workspaces
just build       # Build both workspaces
just validate    # Full validation (lint + test + build)

From workspace directories (direct commands):

# Backend development
cd backend
just dev           # Start Go server locally
just test          # Run backend tests
just validate      # Backend-only validation
just migrate       # Run database migrations

# Frontend development
cd frontend
just dev           # Start Vite dev server
just test          # Run frontend tests
just typecheck     # TypeScript checking
just validate      # Frontend-only validation

# Database operations
cd database
just up            # Start TimescaleDB
just logs          # View database logs
just psql          # Connect to psql

How it works:

  • Delegation: just <workspace> <command> from root → cd <workspace> && just <command>
  • Lazy aliases: just db, just fe, just be for shorter commands
  • Fallback: Workspace justfiles can call root recipes
  • Context-aware: just dev does the right thing based on current directory

Docker Commands

Full Stack:

just dev          # Start database + backend
just dev-stop     # Stop all services
just dev-logs     # Follow logs (all services)

Database (infrastructure commands):

just database up        # Start TimescaleDB
just database down      # Stop TimescaleDB
just database logs      # View database logs
just database psql      # Connect to psql (or: just database shell)
just database status    # Check database health
just database reset     # ⚠️  Reset database (deletes all data)

# Lazy aliases (shorter):
just db up         # Same as: just database up
just db logs       # Same as: just database logs
just db psql       # Same as: just database psql

Database Migrations (application commands):

just backend migrate              # Apply all pending migrations
just backend migrate-down         # Rollback last migration
just backend migrate-status       # Show current migration version
just backend migrate-create foo   # Create new migration (000XXX_foo.up/down.sql)
just backend migrate-force 5      # Force version to 5 (recovery only)

# Lazy aliases (shorter):
just be migrate          # Same as: just backend migrate
just be migrate-status   # Same as: just backend migrate-status

Migrations run automatically on just dev startup. Manual migration commands are useful for:

  • Production deployments
  • Testing migration rollback
  • Creating new migrations
  • Recovery from failed migrations

Native Development (Optional)

If you have Go 1.25+ installed, you can run backend natively:

# Run backend natively (from backend/ directory)
cd backend && just dev       # Starts at localhost:8080

# Or use delegation from root
just backend dev             # Starts at localhost:8080

# Run validation (from root with delegation)
just backend lint            # Format + lint
just backend test            # Run tests
just backend build           # Build binary
just backend validate        # All checks

Note: Docker is the recommended workflow. Native commands are available for those who prefer it.

Validation

Run validation checks using the delegation pattern:

# Full validation (lint, test, build)
just validate

# Combined checks across all workspaces
just lint        # Lint backend + frontend
just test        # Test backend + frontend
just build       # Build backend + frontend

# Backend validation (delegation from root)
just backend validate     # All backend checks
just backend lint         # go fmt + go vet
just backend test         # go test
just backend build        # go build

# Frontend validation (delegation from root)
just frontend validate    # All frontend checks
just frontend lint        # ESLint
just frontend typecheck   # TypeScript
just frontend test        # Vitest unit tests
just frontend build       # Vite production build

# Workspace-specific (from workspace directory)
cd backend && just validate   # Backend-only validation
cd frontend && just validate  # Frontend-only validation

See justfile for all available commands.

Features

MVP (Current)

  • JWT authentication
  • Asset management (CRUD)
  • Location tracking via RFID/BLE
  • MQTT ingestion pipeline
  • Real-time asset location queries

Roadmap

  • Continuous aggregates for historical data
  • REST API with key authentication
  • ERP/WMS integrations
  • Multi-tenant isolation
  • Self-hosted deployment options

Deployment

SaaS (Railway)

# Single container deployment
docker build -t trakrf/platform .
railway up

Self-Hosted

# Customer deployment via docker-compose
docker-compose -f docker-compose.prod.yml up

Load Testing

See load-tests/README.md for the k6 capacity probe — how to run it, current baselines, and what is (and isn't) measured.

License

Business Source License (BSL) - see LICENSE

REST API

Phase 4A - Foundation + User Management (v1)

The backend exposes RESTful JSON APIs under /api/v1:

Health Checks

GET /healthz   # K8s liveness probe
GET /readyz    # K8s readiness probe (with DB check)
GET /health    # Human-friendly health status (JSON)

Accounts

GET    /api/v1/accounts         # List all accounts (paginated)
GET    /api/v1/accounts/:id     # Get account by ID
POST   /api/v1/accounts         # Create new account
PUT    /api/v1/accounts/:id     # Update account
DELETE /api/v1/accounts/:id     # Soft delete account

Users (superadmin only)

Cross-org back office. Every route requires is_superadmin; any other session gets 403. Self-service profile edits go through PATCH /api/v1/users/me. No POST: removed in TRA-1103 — users are created by signup and org invitations.

GET    /api/v1/users            # List all users (paginated)
GET    /api/v1/users/:id        # Get user by ID
PUT    /api/v1/users/:id        # Update user
DELETE /api/v1/users/:id        # Soft delete user

Account Users (RBAC Junction)

GET    /api/v1/accounts/:account_id/users                # List users in account
POST   /api/v1/accounts/:account_id/users                # Add user to account
PUT    /api/v1/accounts/:account_id/users/:user_id       # Update user role/status
DELETE /api/v1/accounts/:account_id/users/:user_id       # Remove user from account

Response Format:

  • Success: {"data": {...}} or {"data": [...], "pagination": {...}}
  • Error: RFC 7807 Problem Details with request ID for tracing

Pagination: ?page=1&per_page=20 (default: page 1, 20 items, max 100)

Full API documentation coming soon at /api/docs.

Releasing

See docs/releasing.md for the production release runbook — tag-before-build, promotion, the migration-ledger relocation ordering, post-deploy verification and rollback.

Contributing

See CONTRIBUTING.md for detailed guidelines on:

  • Development setup and workflow
  • Code style and architecture patterns
  • Testing requirements
  • Pull request process
  • Commit message conventions

About

TrakRF RFID data collection and integration platform

Resources

Code of conduct

Contributing

Security policy

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages