Add three submodules (central-context, mboxer, notification-bridge), devbox-connect as tracked files, and top-level project docs.
3.0 KiB
Scaling Recommendations
1. Extract a shared library
The same patterns are already duplicated in central-context and notification-bridge: BaseSettings with .env, FastAPI lifespan boilerplate, uvicorn entry points, error-to-HTTP-exception translation, test fixtures with temp dirs and settings overrides. At dozens of services this becomes a maintenance problem — fix a bug in the pattern and you're patching it everywhere.
A castle-core (or similar) package that provides a base settings class, standard lifespan wiring, common test fixtures, and health check endpoint would let new services start from ~10 lines of setup code.
2. Standardize project layout
Right now there are three different layouts: src/central_context/, flat notification_bridge/, and single-file convert.py. Pick one (the src/ layout is the most robust) and stick with it. This matters because any top-level tooling that iterates over projects needs predictable structure.
3. Top-level task runner
With dozens of projects, there needs to be a way to run commands across all or some of them. A root Makefile, justfile, or script that can do things like:
make test— run all testsmake test p=central-context— run one project's testsmake lint— lint everythingmake sync—uv syncin all projects
Without this, significant time gets spent just navigating and running repetitive commands.
4. Port and service registry
Ports are currently hardcoded defaults (9000, 9001). With dozens of services, there needs to be a single source of truth for port assignments — even if it's just a services.yaml at the repo root that maps service names to ports.
5. Inter-service configuration
notification-bridge hardcodes http://localhost:9000 as the central-context URL. This pattern doesn't scale — each new service that talks to another service adds more hardcoded URLs in more .env files. Consider either:
- A convention like
CASTLE_{SERVICE_NAME}_URLderived from the registry - A shared config that generates per-service
.envfiles
6. Consistent ruff/pyright configuration
Each project currently has its own ruff rules (devbox-connect selects E,F,I,W while mboxer selects ALL). With dozens of projects, either put a shared ruff.toml at the repo root (ruff walks up to find config) or decide on one standard. Same for pyright — only devbox-connect has it enabled currently.
7. What to defer
- Containerization/orchestration — until deploying somewhere beyond the local machine
- API gateway / service mesh — premature until there are actual traffic patterns
- Distributed tracing / observability — add when debugging cross-service issues becomes painful
- Formal API schema sharing (OpenAPI contracts between services) — FastAPI generates these already; formalize when there are consumers that need stability guarantees
Priority
The highest-leverage first step is the shared library + top-level task runner, since those reduce the marginal cost of adding each new service.