Technical Decisions¶
Editions: OSS. Contributor documentation for this repository.
This chapter records technical choices: FastAPI for the REST API, Python, PostgreSQL, and how the stack is deployed (Compose, Helm, service roles).
REST API Implementation¶
Preloop implements a RESTful HTTP API using FastAPI, which provides: - High performance with Starlette and Pydantic - Automatic OpenAPI documentation generation - Type annotation-based parameter validation - Native async/await support - Dependency injection system - Middleware for authentication, logging, etc.
Language and Framework¶
Python is chosen as the primary language due to its strong ecosystem for machine learning and data processing, which is essential for similarity search and embedding generation. FastAPI is used for the REST API due to its performance, type safety, and automatic OpenAPI documentation generation.
Database¶
PostgreSQL with the PGVector extension is used. The preloop.models module encapsulates all database interaction logic, providing a clean separation from the API and synchronization services. This allows for centralized data management and schema evolution.
Deployment¶
The system is designed to be containerized using Docker, enabling easy deployment in various environments including Kubernetes clusters. Stateless components enable horizontal scaling under load.
- Service roles:
PRELOOP_SERVICE_ROLE(all|api|gateway, defaultall) gates which subsystems boot in a given container: API-only deployments skip gateway-only surfaces and gateway-only deployments skip the MCP server, NATS WS consumer, execution monitor, plugins' API workers, and approval-repair passes.create_applazy-imports API-only routers and MCP/auth so a dedicated gateway does not load the control-plane import graph. Compose already splitsapiandgateway. The Helm chart setsPRELOOP_SERVICE_ROLE=apiandPRELOOP_SERVICE_ROLE=gatewayon those Deployments so Kubernetes pods do not fall back toalland import the control plane into every gateway replica. - Migrations:
docker-compose.ymlanddocker-compose.release.yamlrun schema initialization in a dedicated one-shotmigrateservice that app services wait on (service_completed_successfully); Helm deployments run Alembic via their own lifecycle.start.shstill waits forDATABASE_URLto accept TCP beforeinit_db.pyfor non-compose local runs. - Dev compose:
docker-compose.ymlhealthchecks postgres and NATS and starts api/gateway/scheduler/worker only after both are healthy andmigratehas completed. The Vite dev server honorsVITE_ALLOWED_HOSTSwhen the console is reached by a public hostname. - Health monitoring: The Helm chart ships an optional in-cluster health-monitor deployment (
healthMonitor.*, enabled by default) that polls/api/v1/healthand logs alert lines after consecutive failures. - Release verification:
scripts/release_smoke_test.shboots the release compose file with tagged images and verifies HTTP health, first-user sign-up/login, and restart-loop-free stability; the release workflow runs it as theverify-oss-installgate before publishing a GitHub release. - OSS installer
.env:scripts/install-oss.shwrites Compose.envvalues with$escaped as$$so secrets are not interpolated (and partial secrets are not leaked via compose WARNs). Hand-edits of~/.preloop-oss/.envneed the same escaping.