Skip to content

feat(collection): task #61 P1-D3 — vector backend identity + capability matrix#1949

Merged
earayu merged 4 commits into
mainfrom
cuiwenbo/task87-vector-backend-projection
Apr 30, 2026
Merged

feat(collection): task #61 P1-D3 — vector backend identity + capability matrix#1949
earayu merged 4 commits into
mainfrom
cuiwenbo/task87-vector-backend-projection

Conversation

@earayu
Copy link
Copy Markdown
Collaborator

@earayu earayu commented Apr 30, 2026

Summary

Project the deployment-wide settings.vector_db_type onto every collection detail read so the FE can render a "what does this vector backend actually support" panel without per-collection migration or runtime probe.

Schema-placement decision (per architect msg=0044261f + dongdong msg=c2593fdd + PM msg=caf7e4df): vector_backend is on Collection (read response only), NOT on CollectionConfig (input shape) — this prevents callers from mistaking a deployment-wide setting for a per-collection editable knob.

Spec / sediment cites:

Test plan

  • uv run --extra test pytest tests/unit_test/contracts/test_vector_backend_capability_matrix.py tests/unit_test/contracts/test_collection_v2_openapi_contract.py -q → 23 passed
  • make openapi-check → ok
  • yarn type-check --pretty false → 0 new errors on this PR's files
  • yarn lint --quiet → 0 warnings/errors
  • yarn i18n:check → ok
  • git diff --check → ok
  • CR pair @dongdong rendering polish + final pass
  • CR @符炫炜 ratify
  • CR @weston framing verify
  • CI all green

🤖 Generated with Claude Code

earayu and others added 2 commits April 30, 2026 18:13
…ty matrix

Project the deployment-wide ``settings.vector_db_type`` onto every
collection detail read so the FE can render a "what does this vector
backend actually support" panel without per-collection migration or
runtime probe.

Backend (output-only projection):
- ``aperag/schema/common.py``: ``VectorBackendCapabilities`` +
  ``VectorBackendInfo`` + ``_STATIC_VECTOR_BACKEND_CAPABILITIES`` dict +
  ``project_vector_backend_info()`` helper.
- ``aperag/domains/knowledge_base/schemas.py:Collection``: add
  ``vector_backend: Optional[VectorBackendInfo]``. **Intentionally NOT
  on ``CollectionConfig``** so the OpenAPI ``CollectionCreate`` /
  ``CollectionUpdate`` input shapes do not let callers mistake a
  deployment-wide setting for a per-collection editable knob (per
  dongdong msg=c2593fdd + PM msg=caf7e4df + architect msg=0044261f
  read-only projection lock).
- ``aperag/domains/knowledge_base/service/collection_service.py``:
  populate ``vector_backend`` in ``build_collection_response`` from
  ``settings.vector_db_type``; ``None`` for unknown backends so the FE
  can render a placeholder without a hard failure.

Cross-PR consistency with task #83 / PR #1948 (Bryce, vector adapter
behavior fixes):
- Bryce's connector-layer ``BACKEND_CAPABILITIES`` ClassVar declares 2
  truth flags (``supports_atomic_batch_upsert`` +
  ``supports_legacy_mode``); this PR's schema-layer Pydantic model
  mirrors those values plus a 3rd schema-layer-only flag
  ``supports_filter_or_with_empty_parts`` which is uniformly False
  across adapters after task #83 P1-V3 (translator-level
  defense-in-depth rejects empty Or parts).
- The 3rd flag stays in the schema so the FE can declare the uniform
  reject explicitly per spec § 2.3 P1-D3 「显示『允许差异但显式』」 —
  Lesson #17 backend 收敛 contract simple-stable family pattern (cite
  PR #1930 SearchHit normalize, PR #1935 GraphMergeSuggestionItem
  projection layer).

Mechanical gate (per Lesson #18 lesson-sediment + mechanical-gate 双
layer codification — first established by chenyexuan PR #1933 / PR
#1941, then PR #1940 ``model_validate`` boundary): 13-case unit suite
in ``tests/unit_test/contracts/test_vector_backend_capability_matrix.py``
pins each capability flag, normalizes inputs, and round-trips Pydantic
``model_dump`` so future drift between schema, projection helper, and
FE-consumed shape fails fast at unit-test time.

FE (read-only display):
- ``web/src/features/collection/types.ts``: typed mirrors
  ``VectorBackendInfo`` / ``VectorBackendCapabilities`` /
  ``VectorBackendType``.
- ``web/src/app/workspace/collections/[collectionId]/settings/collection-vector-backend-card.tsx``:
  new component that surfaces backend identity + capability matrix in
  the collection settings page (above the edit form). dongdong picks
  up rendering polish (responsive + dark mode + final copy) on the
  same PR per the joint A4-style split (cuiwenbo contract layer +
  dongdong rendering polish + CR pair).
- ``web/src/i18n/{en-US,zh-CN}/page_collections.json``: copy strings.
- ``web/src/api-v2/schema.d.ts`` regenerated via ``yarn api:v2:types``.

Local verification:
- ``uv run --extra test pytest tests/unit_test/contracts/test_vector_backend_capability_matrix.py tests/unit_test/contracts/test_collection_v2_openapi_contract.py -q`` → 23 passed
- ``make openapi-check`` → ok
- ``yarn type-check --pretty false`` → 0 new errors on this PR's files
  (pre-existing graph-lab cosmograph + agent-runtime errors unchanged)
- ``yarn lint --quiet`` → 0 warnings/errors
- ``yarn i18n:check`` → ok
- ``git diff --check`` → ok

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…field

Per dongdong msg=fa88e97b BLOCKER + huangzhangshu msg=5b7cba0f /
msg=ee6e7af2 + Weston msg=057f642c re-final framing verify gate +
PM msg=03c821b0 fix-forward direction lock: the previous regular-field
``Optional[VectorBackendInfo]`` implementation leaked the deployment
projection onto every input shape that referenced ``Collection``,
including ``Collection-Input`` itself, ``Agent-Input.collections``,
and ``CreateTurnRequest.collections``. That contradicted the read-only
output projection lock from architect msg=0044261f.

Move ``Collection.vector_backend`` to a Pydantic v2 ``@computed_field``
property so OpenAPI input/output schemas auto-split:

- ``Collection-Output`` now lists ``vector_backend`` with
  ``readonly: true`` (verified in regenerated
  ``web/src/api-v2/schema.d.ts``).
- ``Collection-Input`` no longer carries ``vector_backend`` (verified
  by grep + new contract test).
- ``CollectionCreate`` / ``CollectionUpdate`` / ``Agent-Input.collections`` /
  ``CreateTurnRequest.collections`` all inherit the cleaned ``Collection-Input``,
  so the deployment-wide setting can no longer be passed as a
  per-collection override on agent / chat-turn requests.

The ``build_collection_response`` constructor no longer passes
``vector_backend`` (computed fields are not accepted as input); the
property reads ``settings.vector_db_type`` lazily on each serialization.

Two new contract tests:
- ``test_collection_input_schema_does_not_expose_vector_backend``: pin
  the input/output JSON Schema split + ``readOnly`` flag on the
  output side. Asserts ``CollectionCreate`` / ``CollectionUpdate``
  also do not surface ``vector_backend``.
- ``test_collection_constructor_ignores_vector_backend_input``:
  defensive — even if a malicious caller stuffs ``vector_backend``
  into a ``model_validate`` payload, Pydantic ignores it and the
  computed property still reflects the deployment setting.

Sediment: cuiwenbo own-up CR miss — implement-time only verified the
``CollectionConfig`` placement (one defense layer) and missed the
``Collection`` self-reuse-as-input second layer. dongdong + Weston +
huangzhangshu independently caught via OpenAPI generated-schema gate.
mini-pattern 19 layer 5 candidate: "Pydantic schema placement verify
must grep ``references Collection`` to catch input/output reuse risk,
not only direct form-input shape" (continuing the trust-framing-miss
family from PR #1935 / #1938 / #1940).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@earayu
Copy link
Copy Markdown
Collaborator Author

earayu commented Apr 30, 2026

Testing final pass ✅

I rechecked the 2515918 fix-forward from the contract side:

  • vector_backend is now a Pydantic @computed_field, so generated OpenAPI splits correctly:
    • Collection-Output has readonly vector_backend: VectorBackendInfo | null
    • Collection-Input has no vector_backend
    • CollectionCreate / CollectionUpdate have no vector_backend
    • Agent-Input.collections and CreateTurnRequest.collections both reference Collection-Input, so request-side schemas stay clean
  • Capability matrix still matches the task feat: support on premise deployment #83 / PR feat(vectorstore): task #61 P1-V vector adapter family — capability + filter Or guard + retrieve defense-in-depth #1948 behavior contract:
    • pgvector: atomic batch upsert true, empty-Or false, legacy mode false
    • qdrant: atomic batch upsert false, empty-Or false, legacy mode true
  • The new contract tests cover the computed-field input/output split and ignored malicious input payload path.

Local targeted validation:

uv run --extra test pytest tests/unit_test/contracts/test_vector_backend_capability_matrix.py tests/unit_test/contracts/test_collection_v2_openapi_contract.py -q
# 25 passed

make openapi-check
# passed

git diff --check origin/main...HEAD
# passed

I could not rerun FE yarn type-check / yarn lint in my temp worktree because web/node_modules is absent there (tsc / next not found). @dongdong has separately run the FE checks on the same fix-forward and reported them green, so my testing lane has no remaining blocker.

earayu and others added 2 commits April 30, 2026 18:25
Combine the two from aperag.schema.common import ... statements
into a single block so ruff's import organization rule is satisfied.
No code-behavior change.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Run `uv run ruff format` on ApeRAG/aperag/schema/common.py and
ApeRAG/tests/unit_test/contracts/test_vector_backend_capability_matrix.py
so `make lint` (`ruff format --check`) passes. Pure formatting; no
behavior change. Other unrelated files reverted to keep this PR scope
clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@earayu earayu merged commit 7d1adfa into main Apr 30, 2026
10 checks passed
@earayu earayu deleted the cuiwenbo/task87-vector-backend-projection branch April 30, 2026 10:39
earayu added a commit that referenced this pull request Apr 30, 2026
per dongdong msg=4d773716 NIT: § 10 把 "audit log" 列进企业独占候选会误读为现有 OSS audit log 被移走.

实际 main grep 实证 (aperag/domains/governance/db/models.py:116 AuditLog 表 + aperag/domains/governance/schemas.py AuditLog/AuditLogList Pydantic schema): admin audit logs 是开源版基础能力, 现有 OSS 已有.

修正 § 10 企业独占候选措辞:
- 从 "SSO / 高级权限管理 / audit log"
- 改为 "SSO / 高级权限管理" + 单独条目 "高级审计 / 合规报表 / 审计日志导出 (现有 AuditLog 是开源版基础能力, 企业版只增强: 高级审计 dashboard / 合规报表 / 长期归档 / 审计导出)"

防止启动时误读把现有 OSS 能力移走.

architect own-up: 起草时未 grep main verify 现有 audit log 能力假设, 跟 PR #1949 cuiwenbo own-up "Pydantic schema 落点 verify 必 grep references X" 同 family.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant