Files
vocero-client/docs/client/development.md
T

4.2 KiB

Backend development and compatibility

The FastAPI project lives entirely in s2s-client/. It uses uv 0.12.5, Python 3.12, and a committed uv.lock. The frontend and speech pipeline keep their own tooling. Runtime dependency versions match the environment used to capture the pre-migration server; framework upgrades require a separate compatibility review.

Commands

From the repository root:

make -C s2s-client install       # uv sync --locked, including development tools
make -C s2s-client format        # Ruff safe fixes and formatting
make -C s2s-client check         # lock freshness, format, lint, mypy, pytest
make -C s2s-client test-launcher # Bash supervisor integration fixtures
make -C s2s-client test-image    # Docker build and isolated runtime smoke test

Run uv lock inside s2s-client/ when intentionally changing dependencies. Do not install server packages into a shared root environment. The launcher syncs s2s-client/.venv and retains root .env loading, port defaults, readiness checks, and process-group shutdown. Offline starts require the locked packages and Python runtime to have been installed or cached already.

Optional hooks use make -C s2s-client hooks-install; the configuration stays in s2s-client/.pre-commit-config.yaml. make -C s2s-client hooks-run runs the same hooks without installing them. Hooks and Python quality checks apply only to the client service. The server entry points are s2s_client.main:app and the retained server:app shim; use --app-dir s2s-client from the root.

Schema boundaries

models/requests.py retains the existing search, reasoning, and ApiPilot request models, including their defaults, coercion, and ignored extra fields. The queue beacon still accepts malformed JSON and non-object bodies as before; its Pydantic view is applied only after the original object check, and queueId remains unconstrained.

models/responses.py validates structure constructed by this server. Fields owned by external services remain Any where the old parser imposed no type constraint. Object models allow extra fields. Caller profiles can be arbitrary JSON; load-balancer fields remain optional; execution results and error details remain open. Existing provider parsing, authentication precedence, argument filtering, environment parsing, and WebSocket frames are unchanged.

HTTP handlers call validated_json_response: Pydantic validates the payload, then JSONResponse serializes the original object. Returning a dumped model would insert defaults or change values/key order, so do not replace this helper with model serialization without a contract review. Route response_model declarations publish the new response schemas in OpenAPI. Existing request schemas and validation errors remain unchanged. HTTP exceptions retain their existing error shapes; there is no new common error envelope.

Compatibility evidence

tests/fixtures/legacy-contracts.json was captured from the original monolithic server at commit 3d42df5, before refactoring. Tests compare 86 HTTP scenarios, including exact response text, statuses, selected headers, and outgoing mock HTTP requests. They also compare request OpenAPI definitions and representative realtime frames. Additional tests cover response validation and permissive upstream values; the original local HTTP/WebSocket tests remain in the suite.

The captures deliberately preserve unknown fields, omitted fields, unusual JSON values, queue beacon edge cases, permissive tool arguments, and known failures. Examples include reasoning's existing uninitialized local variables in certain configuration combinations, API-key-only tool precheck behavior, the catalog cache's existing key, and relay termination after a suppressed invalid session.update error. Fix those in separately reviewed behavior changes; do not regenerate golden captures to make a refactor pass.

These checks use local fixtures and do not claim exhaustive coverage of all provider responses, live speech models, or production configuration. No deployed services or real credentials are needed. The Docker check verifies the actual runtime image, API configuration, documentation, OpenAPI, and the backend's existing root 404; it removes its temporary container and image afterward.