Files
Giancarlo Erra 70db002796 feat(qdrant): add QDRANT_COLLECTION_PREFIX env var for shared instances
Resolves #49. Reported by @awbait.

When sharing a single Qdrant server across multiple applications
(SocratiCode + Open-WebUI + custom RAG, etc.) or across multiple
SocratiCode instances (per-project, per-environment, per-user), the
fixed `codebase_<id>` / `codegraph_<id>` / `context_<id>` /
`<id>_symgraph_*` / `socraticode_metadata` collection names risk
colliding with other apps and prevent isolation between SocratiCode
instances.

This patch adds an optional QDRANT_COLLECTION_PREFIX env var that, when
set, is prepended verbatim to every Qdrant collection name SocratiCode
creates, queries, lists, or deletes. Default empty string preserves the
existing collection names exactly: fully backwards compatible.

Touchpoints (mechanical, no logic changes):

- src/constants.ts: new QDRANT_COLLECTION_PREFIX export with eager
  validation. Qdrant accepts only [a-zA-Z0-9_-] in collection names; an
  invalid prefix throws at module load with a message naming the
  offending value, before any Qdrant call is attempted.
- src/config.ts: all six collection-name generators
  (collectionName, graphCollectionName, contextCollectionName,
  symgraphMetaCollectionName, symgraphFileCollectionName,
  symgraphIndexCollectionName) prepend the prefix. Generator semantics
  are otherwise unchanged.
- src/services/qdrant.ts: METADATA_COLLECTION (the global
  socraticode_metadata collection used for cross-project state) also
  honours the prefix, so two SocratiCode instances on one Qdrant keep
  their metadata isolated as well as their per-project collections.
  The two startsWith() filters in listCodebaseCollections — used by
  codebase_list_projects to discover this instance's collections —
  build the match prefix from QDRANT_COLLECTION_PREFIX so a prefixed
  instance only sees its own collections, not those of co-tenants.
- src/tools/manage-tools.ts: codebase_list_projects similarly uses the
  prefix in its filters. The projectId extraction (formerly
  c.replace("codebase_", "")) now slices the full
  ${prefix}codebase_ token so the recovered id is correct under any
  prefix; the codegraph cross-reference uses the same prefixed name.

Tests: 20 new test cases in tests/unit/qdrant-collection-prefix.test.ts
covering:

- Default empty prefix preserves the legacy collection-name forms for
  all six generators (regression guard against backward-compat break).
- Empty-string env var is treated identically to unset.
- Non-empty prefix prepends correctly to all six generators, including
  the suffix-style symgraph names.
- Two different prefixes produce disjoint collection-name sets for the
  same projectId (the multi-instance isolation property).
- Validation rejects whitespace, slash, colon, and unicode characters.
- The error message includes the offending value for discoverability.
- Validation accepts the full set of legal characters.

Existing 752 unit tests continue to pass unchanged. Total: 772.

typecheck, biome, and CodeRabbit local review all clean. README
updated to document the new env var alongside the other QDRANT_*
settings, including the user-side responsibility to remove old
collections when changing prefix between runs.

Co-authored-by: awbait <awbait@users.noreply.github.com>
2026-05-05 11:20:33 +01:00
..