| title | QP Conduit Developer Guide | |||
|---|---|---|---|---|
| description | Developer guide for contributing to QP Conduit. Covers prerequisites, project structure, testing, adding commands and modules, Docker and native workflows, and code style. | |||
| date_modified | 2026-04-07 | |||
| ai_context | Developer guide for QP Conduit contributors. Prerequisites: bash 4+, jq, bats-core, Node 24+, Python 3.14. Testing with bats (unit, integration, smoke), vitest + RTL (UI, 225 tests, 97%+ coverage). Docker workflow via make dev/refresh/ui. Native workflow with uvicorn + npm run dev. Code conventions: shellcheck, set -euo pipefail, no eval, quoted variables. | |||
| related |
|
| Tool | Version | Purpose |
|---|---|---|
bash |
4.0+ | Shell scripts |
jq |
1.6+ | JSON processing |
bats-core |
1.10+ | Shell test framework |
node |
24+ (LTS) | Admin dashboard |
npm |
11+ | Package management |
python |
3.14+ | Admin API server |
pip |
Latest | Python dependency management |
shellcheck |
0.9+ | Shell script linter |
docker |
24+ | Container-based development |
Install bats-core from your package manager or from source:
# macOS
brew install bats-core
# Ubuntu/Debian
sudo apt install bats
# From source
git clone https://github.com/bats-core/bats-core.git
cd bats-core && sudo ./install.sh /usr/localconduit/
conduit-preflight.sh Pre-flight checks (sourced by all commands)
conduit-setup.sh Initialize Conduit
conduit-register.sh Register a service
conduit-deregister.sh Deregister a service
conduit-status.sh Show service health status
conduit-monitor.sh Show hardware stats
conduit-certs.sh Manage TLS certificates
conduit-dns.sh Manage DNS entries
server.py FastAPI admin API server
Makefile Build and run automation
Dockerfile Multi-stage Docker build (Node + Python)
docker-compose.yml Docker Compose for the dashboard
requirements.txt Python dependencies
.env.conduit.example Environment variable template
lib/
common.sh Logging, validation, config defaults
audit.sh Structured JSONL audit log + Capsule sealing
registry.sh Service registry CRUD (jq-based JSON)
dns.sh dnsmasq configuration and management
tls.sh TLS certificate lifecycle (Caddy CA)
routing.sh Caddy reverse proxy route management
templates/
Caddyfile.service.tpl Per-service Caddyfile template
ui/
src/
app.tsx Root component with lazy-loaded views
stores/app-store.ts Zustand global state (view, filters, sidebar)
lib/types.ts TypeScript interfaces for all data models
components/
layout/ App shell, sidebar, header
views/
dashboard/ Global health overview
services/ Service list and management
dns/ DNS entry management
tls/ Certificate management
servers/ Server monitoring
routing/ Proxy route management
tests/
unit/ bats unit tests
integration/ bats integration tests
smoke/ End-to-end smoke tests
docs/ Documentation
examples/ Deployment examples
# All tests (unit + integration)
make test
# Unit tests only
make test-unit
# Integration tests only
make test-integration
# Smoke tests (requires a running Conduit instance)
make test-smoke
# Admin UI tests (225 tests, vitest + React Testing Library)
make test-ui
# Admin UI tests with coverage report
docker run --rm -v "$(pwd)/ui:/ui" -w /ui node:24-alpine \
sh -c "npm ci && npx vitest run --coverage"
# All tests + UI type-check
make checkShell tests use bats-core. Each test file lives in tests/unit/ or tests/integration/ and follows test_<module>.bats.
UI tests use Vitest with React Testing Library and happy-dom. Test files are colocated with source (e.g., app-store.test.ts next to app-store.ts). Current coverage: 97.3% statements, 97.2% lines across 17 test files.
- Create
conduit-<name>.shin the project root - Add the shebang and copyright header:
#!/usr/bin/env bash # conduit-<name>.sh # One-line description. # # Copyright 2026 Quantum Pipes Technologies, LLC # SPDX-License-Identifier: Apache-2.0
- Add
set -euo pipefailimmediately after the header - Source
conduit-preflight.sh:SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/conduit-preflight.sh"
- Add a
usage()function with--help|-hhandling - Parse arguments with a
for arg in "$@"loop andcasematching - Validate all inputs using
validate_service_name,_validate_port, etc. - Write an
audit_logentry at the end of each operation - Add a Make target in
Makefile - Add the script to
docker-compose.ymlvolumes - Add the script to
DockerfileCOPY - Write unit tests in
tests/unit/test_<name>.bats - Add an API endpoint in
server.py(if applicable) - Document the command in
docs/COMMANDS.md
- Create
lib/<name>.sh - Add the standard header with
set -euo pipefail - Source
common.sh:SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/common.sh"
- Add the source line to
conduit-preflight.sh(order matters; place after dependencies) - Prefix internal functions with
_(e.g.,_helper_func) - Write unit tests in
tests/unit/test_<name>.bats - Document the module in the architecture docs
- Create
ui/src/components/views/<name>/<name>-view.tsx - Add the view type to
ui/src/stores/app-store.ts(Viewtype union) - Add the URL path mapping in
PATH_TO_VIEWandVIEW_TO_PATHinapp-store.ts - Add a lazy import in
ui/src/app.tsxand add it to theviewsobject - Add the navigation entry in
ui/src/components/layout/sidebar.tsx - Add a keyboard shortcut number in
ui/src/hooks/use-keyboard.ts - Add any new API types to
ui/src/lib/types.ts - Create an API module in
ui/src/api/if the view needs new endpoints - Add a
ViewBlankSlateempty state for the zero-data case - Write tests in
ui/src/components/views/<name>/<name>-view.test.tsx - Run
make ui-typecheckto verify
The recommended development workflow uses Docker:
# Start the dashboard (builds UI + starts server)
make dev
# Rebuild after code changes
make refresh
# Stop
make stop
# View logs
make logsThe Docker Compose setup:
- Builds the React UI in a Node 24 Alpine stage
- Runs the FastAPI server with Python 3.14 and uvicorn
- Mounts shell scripts and lib/ as volumes for live reloading
- Mounts the config directory for access to services.json and audit.log
- Mounts the Docker socket for container monitoring
- Exposes port 9999
For faster iteration without Docker:
# Start UI dev server via Docker (port 5173, with HMR, no local Node required)
make ui
# In another terminal: start the API server
pip install -r requirements.txt
uvicorn server:app --host 0.0.0.0 --port 9999 --reload
# Build the UI for production
make ui-buildThe make ui target runs Vite inside a Node 24 Docker container with the ui/ directory mounted for hot module replacement. No local Node.js installation required. The Vite dev server proxies /api/* requests to the FastAPI server automatically.
- Every script starts with
set -euo pipefail - No
evalanywhere. This is enforced. - Quote all variable expansions:
"$var", not$var - Use
localfor all function-scoped variables - Validate all user input with strict regexes (
^[a-zA-Z0-9_-]+$) - Use
jqfor all JSON manipulation (no sed/awk on JSON) - Write structured JSON audit entries for state-changing operations
- Run
shellcheckon all.shfiles before committing
- Type hints on all function signatures
- Use
subprocess.runwithcapture_output=Trueandtimeout - Never use
shell=Truein subprocess calls - Use
Pathobjects for file paths
- Strict mode enabled
- All data types defined in
ui/src/lib/types.ts - Zustand for global state
- Lazy-loaded views for code splitting
- Semantic color tokens from the theme (no hardcoded colors)
Use conventional commit prefixes with scope:
feat(conduit): add GPU temperature alerting
fix(dns): handle empty hosts file on first run
test(registry): add tests for duplicate service detection
docs(guide): add certificate rotation section
polish(ui): improve service table responsiveness
chore(docker): update Node base image to 22.5
Scopes: conduit, dns, tls, routing, registry, audit, monitor, ui, docker, docs
- Commands Reference: What each script does
- Admin UI: Dashboard architecture
- API Reference: REST API documentation
- Architecture: System design