Skip to content

fix: align collection name validation with zvec (allow hyphens) - #12

Open
webdevsamran wants to merge 5 commits into
zvec-ai:mainfrom
webdevsamran:fix/issue-9
Open

webdevsamran wants to merge 5 commits into
zvec-ai:mainfrom
webdevsamran:fix/issue-9

Conversation

@webdevsamran

Copy link
Copy Markdown

Fixes #9

Aligns Studio collection name validation with the underlying zvec engine to accept hyphens and numbers at the start of names.

Changes

  • Backend: updated _COLLECTION_NAME_RE in apps/backend/zvec_studio/schemas/collection.py from ^[A-Za-z][A-Za-z0-9_]{2,63}$ to ^[A-Za-z0-9_-]{3,64}$, including collection creation and snapshot import rename validation.
  • Frontend: updated COLLECTION_NAME_RE in apps/frontend/src/pages/collections/CreateCollectionDialog.tsx to /^[A-Za-z0-9_-]{3,64}$/.
  • Locales: updated error messages in en.json and zh.json.
  • Tests \u0026 Docs: updated unit tests in apps/backend/tests/unit/test_collections_schemas.py to verify valid hyphenated names (e.g., pr-new-collection, -start, end-, a-b) and documentation in docs/backend.md.

Signed-off-by: webdevsamran <samranwebdev2000@gmail.com>
Signed-off-by: webdevsamran <samranwebdev2000@gmail.com>

@feihongxu0824 feihongxu0824 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes the immediate mismatch, but it still copies Zvec's collection-name regex into Studio, which preserves the duplication that caused #9. Could we make Zvec/SDK the source of truth for engine-level name validation, pass the name through, and translate SDK validation failures into a stable Studio API error?

The remaining recent / open restrictions are caused by route layout rather than collection-domain rules: static endpoints such as /collections/recent and /collections/open share the /collections/{name} namespace. Those operations should move out of the resource-name namespace—for example, POST /collections:open and GET /workspace/recent-collections—after which _RESERVED_COLLECTION_NAMES can be removed. Existing routes can remain temporarily as deprecated aliases if compatibility is required.

import './CreateCollectionDialog.css';

const COLLECTION_NAME_RE = /^[A-Za-z][A-Za-z0-9_]{2,63}$/;
const COLLECTION_NAME_RE = /^[A-Za-z0-9_-]{3,64}$/;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid duplicating the engine regex in the frontend. Otherwise Studio can again block names accepted by a future Zvec version. The UI can check that the name is present and surface the normalized backend validation error; if exact client-side constraints are required, they should come from a shared or generated contract.

await userEvent.type(screen.getByTestId('zv-create-path'), '/tmp/foo');
await userEvent.click(screen.getByTestId('zv-create-submit'));

expect(screen.queryByText(/Name must match/)).not.toBeInTheDocument();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only asserts that an error is not currently visible. Please wait for and assert the POST request, including body.schema.name, so the test proves that the hyphenated name was actually accepted and submitted.

…lean frontend regex

- Remove duplicated collection name regex from CreateCollectionDialog and let
  backend/SDK serve as single source of truth for name format validation.
- Surface backend INVALID_SCHEMA/VALIDATION_ERROR directly to field error
  state and toast notification.
- Update CreateCollectionDialog.test.tsx to assert POST schema payload with
  body.schema.name and verify backend error presentation.
- Update CollectionSchema to enforce non-empty names and REST route path
  reservations while delegating format validation to Zvec SDK.

Signed-off-by: Samran Asif <samranwebdev2000@gmail.com>
@webdevsamran

Copy link
Copy Markdown
Author

Hi @feihongxu0824 👋 Thanks for the review and architectural guidance!

Addressed in commit \2407f60:

  1. Frontend Regex Removed: Completely removed the duplicated engine regex from \CreateCollectionDialog.tsx. The UI now only checks that the name is present, delegating format validation entirely to the backend and Zvec SDK.
  2. Normalized Backend Error Surfacing: When the backend/SDK rejects a collection schema with \INVALID_SCHEMA\ or \VALIDATION_ERROR, the normalized error is surfaced both directly on the name field error state and through the toast notification.
  3. POST Payload Test Assertion: Updated \CreateCollectionDialog.test.tsx\ to wait for and assert the submitted POST request payload, verifying \�ody.schema.name === 'my-valid-collection', and added explicit coverage for backend validation error presentation.
  4. Backend Single Source of Truth: Updated \CollectionSchema\ and \CollectionImportRequest\ to pass collection names through to the SDK (which maps engine validation failures to \InvalidSchemaError), while preserving REST gateway reserved route path guards (
    ecent, \open).

@feihongxu0824 feihongxu0824 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks—the validation ownership changes look good. The route coupling remains because recent and open are still reserved. Please create and link a follow-up issue or PR for the route migration so this architectural part is not lost.

One compatibility detail: GET /collections/recent cannot remain as a deprecated alias while also allowing a collection named recent, because the HTTP method and path are identical. Supporting both requires either a clean route break, API versioning, or moving item access to a different namespace. A clean target would be POST /collections:open, POST /collections:import, and GET /workspace/recent-collections, after which the reserved-name guards can be removed.

err.error.code === 'VALIDATION_ERROR' ||
err.error.code === 'INVALID_SCHEMA'
) {
setErrors((prev) => ({

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

INVALID_SCHEMA is not necessarily a collection-name error; it is also used for unrelated failures such as a missing parent directory, invalid fields, vectors, or index configuration. Mapping every INVALID_SCHEMA / VALIDATION_ERROR to errors.name can therefore display an unrelated error under the Name field. Please keep generic schema errors at the form/toast level, and only set errors.name when the backend returns an explicit field location such as schema.name.

… field location

Signed-off-by: Samran Asif <samranwebdev2000@gmail.com>
@webdevsamran

Copy link
Copy Markdown
Author

Thank you @feihongxu0824! I have opened follow-up issue #13 to track the route decoupling and removal of reserved collection names: #13

Copy link
Copy Markdown
Collaborator

CI is currently failing consistently across all backend matrices on the same test:

tests/unit/test_edge_cases.py::test_collection_name_exceeds_max_length_rejected
expected: 422
actual:   400

This appears to be an outdated assertion after moving engine-level collection-name validation from Pydantic to Zvec/SDK. The request now reaches the SDK and is normalized as INVALID_SCHEMA (400) rather than a Pydantic VALIDATION_ERROR (422). Please update the test to assert the new API contract, ideally including the stable error code:

assert resp.status_code == 400
assert resp.json()["code"] == "INVALID_SCHEMA"

Frontend Node 20/22 and E2E are green; the backend failures all point to this same expectation mismatch.

…NVALID_SCHEMA

Signed-off-by: Samran Asif <samranwebdev2000@gmail.com>
@webdevsamran

Copy link
Copy Markdown
Author

Hi @feihongxu0824 👋 Thanks for catching that!

Updated the expectation in tests/unit/test_edge_cases.py (test_collection_name_exceeds_max_length_rejected) in commit b8cca7f to assert resp.status_code == 400 and resp.json()["code"] == "INVALID_SCHEMA" per the new SDK validation normalization contract.

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.

Align collection name validation with zvec (allow hyphens)

2 participants