From 2b053af248153b53c7c0b90a11777225da142337 Mon Sep 17 00:00:00 2001 From: Mike Stankavich Date: Mon, 31 Aug 2026 06:31:25 -0500 Subject: [PATCH] docs: make the contributor quickstart actually run TRA-1219. Every command in the getting-started path was dead. A stranger following CONTRIBUTING.md failed at step 4 and never reached step 5. The Quick Setup described an architecture the repo left behind: raw docker-compose plus `go run cmd/migrate/main.go`, predating just, direnv and the bootstrap step. Verified rather than assumed -- each of these was checked against the tree: cp backend/.env.example no such file, and no env sample in that dir cp frontend/.env.example same go run cmd/migrate/main.go no such path; migrations run via just go test ./tests/integration no such dir; integration tests are in-package behind a build tag go run cmd/server/main.go no such path; the entrypoint is main.go cd tests/api && pnpm test no top-level tests/ dir at all `just` was not even listed as a required tool, though it is the entry point for every workflow in the repo. Neither was direnv, and pnpm was named only as "Node.js". Replaced with the path the README documents and the justfile implements: configure .env.local, just bootstrap, just dev, just test. Every recipe and file named in the new text was confirmed to exist. Also corrected, same rot, found by auditing the whole file rather than the lines that were reported: - Adding an API endpoint pointed at backend/api/routes.go; the router is backend/internal/cmd/serve/router.go - Database changes pointed at database/migrations/; it is backend/migrations/, and the step that makes CI pass -- `just backend migrate-checksums` -- was missing entirely - The frontend section described Redux and Storybook. Neither is a dependency; the app uses zustand and TanStack Query Left alone deliberately: "test the migration up and down" reads like the same rot but is correct -- downs are still written, including for the four most recent migrations. Checked before editing. Refs: TRA-1219 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01W7p2hFrE6ZFWS91XvyFQcV --- CONTRIBUTING.md | 96 +++++++++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 43 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 24364bc7..572f76a6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,11 +9,12 @@ TrakRF Platform is an RFID/BLE asset tracking system for manufacturing and logis ## Before You Start ### Required Tools +- **just** - The entry point for every workflow. Run recipes from the project root - **Go 1.25+** - For backend development (required for Air hot-reload) -- **Node.js 18+** - For frontend development -- **Docker & Docker Compose** - For running dependencies +- **Node.js 18+ and pnpm 9+** - For frontend development. pnpm only; use `pnpm dlx`, never `npx` +- **Docker & Docker Compose** - Runs TimescaleDB and the backend +- **direnv** - Auto-loads `.env.local` - **Git** - For version control -- **TimescaleDB** - Via Docker or TigerData cloud ### Quick Setup ```bash @@ -23,21 +24,29 @@ TrakRF Platform is an RFID/BLE asset tracking system for manufacturing and logis git clone https://github.com/YOUR_USERNAME/platform.git cd platform -# 3. Start dependencies -docker-compose up -d timescaledb +# 3. Configure environment. Optional — every value has a working local default, +# so the stack comes up with no env file at all. You need this only for +# things with no sensible default, such as MQTT credentials. +cp .env.local.example .env.local +direnv allow -# 4. Set up environment -cp backend/.env.example backend/.env -cp frontend/.env.example frontend/.env +# 4. Generate the embedded build targets. Takes a couple of minutes cold and +# needs no supervision, so it is worth backgrounding. Without it the build +# fails with `pattern frontend/dist: no matching files found`. +just bootstrap -# 5. Run migrations -cd backend && go run cmd/migrate/main.go up +# 5. Start the stack: database, then migrations, then the backend +just dev -# 6. Run tests -go test ./... -cd ../frontend && pnpm test +# 6. Run the tests +just test ``` +There is **one** local env file, `.env.local`, and it holds connection *parts* +rather than URLs. `just bootstrap` symlinks `.env` to it, because docker compose +reads `.env` while direnv reads `.env.local`. See the README for why that matters +and for the local database roles — this guide does not restate it. + ## Making Changes ### 1. Create a Branch @@ -84,20 +93,23 @@ export async function fetchAssetLocation(assetId: string): Promise { ``` ### 3. Test Your Changes + +Run recipes from the project root; `just` delegates into each workspace. + ```bash -# Backend tests -cd backend -go test ./... -go test -race ./... # Race condition check - -# Frontend tests -cd frontend -pnpm test -pnpm run lint - -# Integration tests (requires running services) -docker-compose up -d -go test ./tests/integration -tags=integration +# Everything — lint, test and build across backend, frontend, cli and database +just validate + +# Or a single workspace +just backend test +just frontend test +just lint + +# Integration tests. They are in-package behind a build tag, not a separate +# directory, and they need a live database plus PG_ADMIN_URL — without it the +# whole package fails at setup rather than skipping. +just database up +just backend test-integration ``` ### 4. Commit Your Work @@ -135,13 +147,11 @@ describe('Asset Service', () => { ### API Integration Tests ```bash -# Run full stack locally -docker-compose up -d -cd backend && go run cmd/server/main.go & -cd frontend && pnpm dev & +# Run the full stack locally: database, migrations, then backend and frontend +just dev-local -# Run API tests -cd tests/api && pnpm test +# Run the API contract tests against it +just test-contract ``` ## Submitting Your Work @@ -171,24 +181,24 @@ cd tests/api && pnpm test ## Common Tasks ### Adding a New API Endpoint -1. Define the route in `backend/api/routes.go` -2. Implement handler in appropriate controller -3. Add service layer logic +1. Define the route in `backend/internal/cmd/serve/router.go` +2. Implement the handler under `backend/internal/handlers/` +3. Add service layer logic under `backend/internal/services/` 4. Write tests for handler and service -5. Update API documentation +5. Update the OpenAPI annotations — the spec is generated from Go, never hand-edited ### Adding a Frontend Feature -1. Create component in appropriate directory +1. Create the component in the appropriate directory 2. Add API client code in `services/` -3. Update relevant Redux store/hooks +3. Update the relevant store or hook — this app uses zustand and TanStack Query 4. Add component tests -5. Update Storybook if applicable ### Database Changes -1. Create migration in `database/migrations/` -2. Test migration up and down -3. Update repository interfaces -4. Consider TimescaleDB features (continuous aggregates, compression) +1. Create the migration in `backend/migrations/` +2. Run `just backend migrate-checksums` — **CI fails without it**, and applied migrations are immutable +3. Test the migration up and down +4. Update repository interfaces +5. Consider TimescaleDB features (continuous aggregates, compression) ## Cutting a Release