chore(productsvc): top-level /v1 — drop residual /api/ prefix (#47)

Rename cloud-api's own public product routes from /api/<route> to
top-level /v1/<route>, per the openapi v1.0.0 lock-in (no /api/ prefix;
the subdomain is api.* so /api/ double-prefixes):

  /api/search-docs/indexes -> /v1/search-docs/indexes
  /api/search-docs/stats   -> /v1/search-docs/stats
  /api/vector/collections  -> /v1/vector/collections
  /api/vector/stats        -> /v1/vector/stats

These are the only /api/ paths cloud-api REGISTERS (serves). The remaining
/api/ literals are upstream calls cloud-api MAKES to other services that
genuinely serve /api/ — left untouched:
  - evalsvc: /api/public/* (Langfuse console API proxy targets)
  - o11ysvc: /v1/o11y/* -> /api/* runtime rewrite (destination)
  - pricingsvc: openrouter.ai/api/v1/models (external)

Hard cutover (no dual-serving, per no-backwards-compat). Coordinated with:
universe cloud-api-v1 AUTH_PUBLIC_PATHS, python-sdk + hanzo-docs RAG
clients, and the openapi cloud spec — all moving to /v1 together.
This commit is contained in:
2026-06-30 17:06:27 -07:00
committed by GitHub
parent c6c7399fd4
commit 513be0c3ba
2 changed files with 7 additions and 7 deletions
+6 -6
View File
@@ -1,8 +1,8 @@
// Package productsvc exposes the read-only Search and Vector product surfaces
// the Hanzo console panels call at api.cloud.hanzo.ai, per HIP-0106.
//
// The console's Search/Indexes and Vector panels are hardcoded to call
// https://api.cloud.hanzo.ai/api/search-docs/* and /api/vector/* with a
// The console's Search/Indexes and Vector panels call
// https://api.hanzo.ai/v1/search-docs/* and /v1/vector/* with a
// bearer key (HANZO_SEARCH_API_KEY / HANZO_VECTOR_API_KEY). cloud-api is the
// single edge that owns those paths: this subsystem proxies them to the
// in-cluster Meilisearch (search.hanzo.svc) and Qdrant (vector.hanzo.svc)
@@ -77,7 +77,7 @@ func Mount(app *zip.App, deps cloud.Deps) error {
cfg := loadConfig()
// ── Search (Meilisearch-backed) ───────────────────────────────────
app.Get("/api/search-docs/indexes", func(c *zip.Ctx) error {
app.Get("/v1/search-docs/indexes", func(c *zip.Ctx) error {
if err := authorize(c, cfg.searchKey); err != nil {
return err
}
@@ -101,7 +101,7 @@ func Mount(app *zip.App, deps cloud.Deps) error {
return c.JSON(http.StatusOK, map[string]any{"indexes": out})
})
app.Get("/api/search-docs/stats", func(c *zip.Ctx) error {
app.Get("/v1/search-docs/stats", func(c *zip.Ctx) error {
if err := authorize(c, cfg.searchKey); err != nil {
return err
}
@@ -126,7 +126,7 @@ func Mount(app *zip.App, deps cloud.Deps) error {
})
// ── Vector (Qdrant-backed) ────────────────────────────────────────
app.Get("/api/vector/collections", func(c *zip.Ctx) error {
app.Get("/v1/vector/collections", func(c *zip.Ctx) error {
if err := authorize(c, cfg.vectorKey); err != nil {
return err
}
@@ -138,7 +138,7 @@ func Mount(app *zip.App, deps cloud.Deps) error {
return c.JSON(http.StatusOK, map[string]any{"collections": cols})
})
app.Get("/api/vector/stats", func(c *zip.Ctx) error {
app.Get("/v1/vector/stats", func(c *zip.Ctx) error {
if err := authorize(c, cfg.vectorKey); err != nil {
return err
}
+1 -1
View File
@@ -51,7 +51,7 @@ import (
_ "github.com/hanzoai/cloud/clients/mlsvc" // order 130 — /v1/ml/*,/v1/train/*
// Console Search/Vector product panels (browser-facing read surface).
_ "github.com/hanzoai/cloud/clients/productsvc" // order 145 — /api/search-docs/*, /api/vector/*
_ "github.com/hanzoai/cloud/clients/productsvc" // order 145 — /v1/search-docs/*, /v1/vector/*
// Installs the o11y runtime handler (reverse proxy to the dedicated o11y
// Deployment) so hanzoai/o11y's /v1/o11y/* surface serves real telemetry