diff --git a/database/queries/registry_entries.sql b/database/queries/registry_entries.sql index 1280d95b..306215a6 100644 --- a/database/queries/registry_entries.sql +++ b/database/queries/registry_entries.sql @@ -99,6 +99,10 @@ SELECT e.entry_type, SELECT e.entry_type, e.name, v.version, + v.title, + v.description, + v.created_at, + v.updated_at, src.name AS source_name, rs.position FROM registry_source rs diff --git a/docs/thv-registry-api/docs.go b/docs/thv-registry-api/docs.go index 1ff3b365..69badc08 100644 --- a/docs/thv-registry-api/docs.go +++ b/docs/thv-registry-api/docs.go @@ -122,15 +122,30 @@ const docTemplate = `{ }, "github_com_stacklok_toolhive-registry-server_internal_service.RegistryEntryInfo": { "properties": { + "createdAt": { + "type": "string" + }, + "description": { + "type": "string" + }, "entryType": { "type": "string" }, "name": { "type": "string" }, + "position": { + "type": "integer" + }, "sourceName": { "type": "string" }, + "title": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, "version": { "type": "string" } diff --git a/docs/thv-registry-api/swagger.json b/docs/thv-registry-api/swagger.json index 96401075..e2eac076 100644 --- a/docs/thv-registry-api/swagger.json +++ b/docs/thv-registry-api/swagger.json @@ -115,15 +115,30 @@ }, "github_com_stacklok_toolhive-registry-server_internal_service.RegistryEntryInfo": { "properties": { + "createdAt": { + "type": "string" + }, + "description": { + "type": "string" + }, "entryType": { "type": "string" }, "name": { "type": "string" }, + "position": { + "type": "integer" + }, "sourceName": { "type": "string" }, + "title": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, "version": { "type": "string" } diff --git a/docs/thv-registry-api/swagger.yaml b/docs/thv-registry-api/swagger.yaml index 2ee43748..ab449349 100644 --- a/docs/thv-registry-api/swagger.yaml +++ b/docs/thv-registry-api/swagger.yaml @@ -81,12 +81,22 @@ components: type: object github_com_stacklok_toolhive-registry-server_internal_service.RegistryEntryInfo: properties: + createdAt: + type: string + description: + type: string entryType: type: string name: type: string + position: + type: integer sourceName: type: string + title: + type: string + updatedAt: + type: string version: type: string type: object diff --git a/internal/api/v1/routes_test.go b/internal/api/v1/routes_test.go index 5b3f94c0..310af036 100644 --- a/internal/api/v1/routes_test.go +++ b/internal/api/v1/routes_test.go @@ -677,10 +677,12 @@ func TestListRegistryEntries(t *testing.T) { registryName: "my-registry", mockReturn: []service.RegistryEntryInfo{ { - EntryType: "MCP", - Name: "my-server", - Version: "1.0.0", - SourceName: "src1", + EntryType: "MCP", + Name: "my-server", + Version: "1.0.0", + Title: "My Server", + Description: "A test server", + SourceName: "src1", }, }, wantStatus: http.StatusOK, @@ -730,6 +732,10 @@ func TestListRegistryEntries(t *testing.T) { err = json.Unmarshal(rr.Body.Bytes(), &resp) require.NoError(t, err) assert.Len(t, resp.Entries, tt.wantLen) + if tt.wantLen > 0 { + assert.Equal(t, tt.mockReturn[0].Title, resp.Entries[0].Title) + assert.Equal(t, tt.mockReturn[0].Description, resp.Entries[0].Description) + } } }) } diff --git a/internal/db/sqlc/registry_entries.sql.go b/internal/db/sqlc/registry_entries.sql.go index 66a98582..e6422733 100644 --- a/internal/db/sqlc/registry_entries.sql.go +++ b/internal/db/sqlc/registry_entries.sql.go @@ -212,6 +212,10 @@ const listEntriesByRegistry = `-- name: ListEntriesByRegistry :many SELECT e.entry_type, e.name, v.version, + v.title, + v.description, + v.created_at, + v.updated_at, src.name AS source_name, rs.position FROM registry_source rs @@ -223,11 +227,15 @@ SELECT e.entry_type, ` type ListEntriesByRegistryRow struct { - EntryType EntryType `json:"entry_type"` - Name string `json:"name"` - Version string `json:"version"` - SourceName string `json:"source_name"` - Position int32 `json:"position"` + EntryType EntryType `json:"entry_type"` + Name string `json:"name"` + Version string `json:"version"` + Title *string `json:"title"` + Description *string `json:"description"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + SourceName string `json:"source_name"` + Position int32 `json:"position"` } func (q *Queries) ListEntriesByRegistry(ctx context.Context, registryID uuid.UUID) ([]ListEntriesByRegistryRow, error) { @@ -243,6 +251,10 @@ func (q *Queries) ListEntriesByRegistry(ctx context.Context, registryID uuid.UUI &i.EntryType, &i.Name, &i.Version, + &i.Title, + &i.Description, + &i.CreatedAt, + &i.UpdatedAt, &i.SourceName, &i.Position, ); err != nil { diff --git a/internal/service/db/impl_registry.go b/internal/service/db/impl_registry.go index 07f824cf..48a08185 100644 --- a/internal/service/db/impl_registry.go +++ b/internal/service/db/impl_registry.go @@ -426,12 +426,26 @@ func (s *dbService) ListRegistryEntries(ctx context.Context, registryName string // Map each row directly to RegistryEntryInfo (flat, no grouping) result := make([]service.RegistryEntryInfo, 0, len(rows)) for _, row := range rows { - result = append(result, service.RegistryEntryInfo{ + info := service.RegistryEntryInfo{ EntryType: string(row.EntryType), Name: row.Name, Version: row.Version, SourceName: row.SourceName, - }) + Position: row.Position, + } + if row.Title != nil { + info.Title = *row.Title + } + if row.Description != nil { + info.Description = *row.Description + } + if row.CreatedAt != nil { + info.CreatedAt = *row.CreatedAt + } + if row.UpdatedAt != nil { + info.UpdatedAt = *row.UpdatedAt + } + result = append(result, info) } span.SetAttributes(otel.AttrResultCount.Int(len(result))) diff --git a/internal/service/service.go b/internal/service/service.go index 87d5fa0b..cccee491 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -231,10 +231,15 @@ type SourceEntriesResponse struct { // RegistryEntryInfo represents a lightweight entry in a registry listing. type RegistryEntryInfo struct { - EntryType string `json:"entryType"` - Name string `json:"name"` - Version string `json:"version"` - SourceName string `json:"sourceName"` + EntryType string `json:"entryType"` + Name string `json:"name"` + Version string `json:"version"` + Title string `json:"title,omitempty"` + Description string `json:"description,omitempty"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + SourceName string `json:"sourceName"` + Position int32 `json:"position"` } // RegistryEntriesResponse is the JSON envelope for listing registry entries.