feat: reuse hub-core base schemas

This commit is contained in:
2026-06-07 16:32:16 +02:00
parent 3b48ce52a3
commit 8428a02f6c
5 changed files with 73 additions and 74 deletions

View File

@@ -87,6 +87,7 @@ async def register_repo(
slug=body.slug,
name=body.name,
local_path=body.local_path,
host_paths=body.host_paths,
remote_url=body.remote_url,
git_fingerprint=body.git_fingerprint,
description=body.description,

View File

@@ -3,41 +3,13 @@ from datetime import datetime
from pydantic import BaseModel, ConfigDict
# ---------------------------------------------------------------------------
# Capability Catalog schemas
# ---------------------------------------------------------------------------
class CatalogCreate(BaseModel):
domain: str # slug, resolved to domain_id in router
capability_type: str
title: str
description: str | None = None
keywords: list[str] = []
repo_slug: str | None = None # optional repo attribution
class CatalogPatch(BaseModel):
repo_slug: str | None = None
description: str | None = None
keywords: list[str] | None = None
status: str | None = None
class CatalogRead(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: uuid.UUID
domain_slug: str
repo_id: uuid.UUID | None = None
repo_slug: str | None = None
capability_type: str
title: str
description: str | None = None
keywords: list[str] = []
status: str
created_at: datetime
updated_at: datetime
from hub_core.schemas.capability import (
CapabilityRequestDispute,
CapabilityRequestStatusPatch,
CatalogCreate,
CatalogPatch,
CatalogRead,
)
# ---------------------------------------------------------------------------
@@ -60,11 +32,6 @@ class CapabilityRequestAccept(BaseModel):
fulfilling_workstream_id: uuid.UUID | None = None
class CapabilityRequestStatusPatch(BaseModel):
status: str # in_progress | ready_for_review | completed | rejected | withdrawn
note: str | None = None
class CapabilityRequestPatch(BaseModel):
catalog_entry_id: uuid.UUID | None = None
priority: str | None = None
@@ -72,12 +39,6 @@ class CapabilityRequestPatch(BaseModel):
fulfilling_workstream_id: uuid.UUID | None = None
class CapabilityRequestDispute(BaseModel):
reason: str
disputed_by: str
suggested_domain: str | None = None
class CapabilityRequestReroute(BaseModel):
note: str
rerouted_by: str

View File

@@ -2,17 +2,16 @@ import uuid
from datetime import date, datetime
from typing import Any, Literal
from pydantic import BaseModel, ConfigDict, Field
from pydantic import BaseModel, Field
from hub_core.schemas.managed_repo import (
RepoCreate as CoreRepoCreate,
RepoPathRegister,
RepoRead as CoreRepoRead,
)
class RepoCreate(BaseModel):
domain_slug: str
slug: str
name: str
local_path: str | None = None
remote_url: str | None = None
git_fingerprint: str | None = None
description: str | None = None
class RepoCreate(CoreRepoCreate):
topic_id: uuid.UUID | None = None
@@ -26,12 +25,6 @@ class RepoUpdate(BaseModel):
last_state_synced_at: datetime | None = None
class RepoPathRegister(BaseModel):
"""Register a machine-local path for a repo on a specific host."""
host: str
path: str
class RepoOnboardRequest(BaseModel):
"""Start scripted onboarding for a working copy that is visible to State Hub."""
domain_slug: str
@@ -49,19 +42,7 @@ class RepoOnboardResult(BaseModel):
stderr: str = ""
class RepoRead(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: uuid.UUID
domain_id: uuid.UUID
domain_slug: str # derived from domain relationship
slug: str
name: str
local_path: str | None = None
host_paths: dict = {}
remote_url: str | None = None
git_fingerprint: str | None = None
description: str | None = None
status: str
class RepoRead(CoreRepoRead):
topic_id: uuid.UUID | None = None
sbom_source: str | None = None
last_sbom_at: datetime | None = None

View File

@@ -1,8 +1,23 @@
from api.schemas.agent_message import MessageCreate
from api.schemas.capability_request import (
CapabilityRequestDispute,
CapabilityRequestStatusPatch,
CatalogCreate,
CatalogPatch,
CatalogRead,
)
from api.schemas.doi import DoIReport
from api.schemas.domain import DomainCreate, DomainRead, DomainRename, DomainUpdate
from api.schemas.managed_repo import RepoCreate, RepoPathRegister, RepoRead
from api.schemas.tpsc import GDPR_WARNING_LEVELS, TPSCCatalogRead, TPSCGDPRReport
from hub_core.schemas.agent_message import MessageCreate as CoreMessageCreate
from hub_core.schemas.capability import (
CapabilityRequestDispute as CoreCapabilityRequestDispute,
CapabilityRequestStatusPatch as CoreCapabilityRequestStatusPatch,
CatalogCreate as CoreCatalogCreate,
CatalogPatch as CoreCatalogPatch,
CatalogRead as CoreCatalogRead,
)
from hub_core.schemas.doi import DoIReport as CoreDoIReport
from hub_core.schemas.domain import (
DomainCreate as CoreDomainCreate,
@@ -10,6 +25,11 @@ from hub_core.schemas.domain import (
DomainRename as CoreDomainRename,
DomainUpdate as CoreDomainUpdate,
)
from hub_core.schemas.managed_repo import (
RepoCreate as CoreRepoCreate,
RepoPathRegister as CoreRepoPathRegister,
RepoRead as CoreRepoRead,
)
from hub_core.schemas.tpsc import (
GDPR_WARNING_LEVELS as CORE_GDPR_WARNING_LEVELS,
TPSCCatalogRead as CoreTPSCCatalogRead,
@@ -32,6 +52,25 @@ def test_state_hub_reexports_core_domain_base_schemas() -> None:
assert DomainUpdate is CoreDomainUpdate
def test_state_hub_reexports_core_capability_base_schemas() -> None:
assert CatalogCreate is CoreCatalogCreate
assert CatalogPatch is CoreCatalogPatch
assert CatalogRead is CoreCatalogRead
assert CapabilityRequestDispute is CoreCapabilityRequestDispute
assert CapabilityRequestStatusPatch is CoreCapabilityRequestStatusPatch
def test_state_hub_reexports_core_repo_path_schema() -> None:
assert RepoPathRegister is CoreRepoPathRegister
def test_state_hub_repo_schemas_extend_core_contracts() -> None:
assert issubclass(RepoCreate, CoreRepoCreate)
assert issubclass(RepoRead, CoreRepoRead)
assert "topic_id" in RepoCreate.model_fields
assert "last_state_synced_at" in RepoRead.model_fields
def test_state_hub_reexports_core_tpsc_schemas() -> None:
assert TPSCCatalogRead is CoreTPSCCatalogRead
assert TPSCGDPRReport is CoreTPSCGDPRReport

View File

@@ -75,6 +75,23 @@ class TestDomains:
assert r.status_code == 409
# ---------------------------------------------------------------------------
# Repo tests
# ---------------------------------------------------------------------------
class TestRepos:
async def test_create_persists_host_paths(self, client):
await _create_domain(client)
r = await client.post("/repos/", json={
"domain_slug": "testdomain",
"slug": "hosted-repo",
"name": "Hosted Repo",
"host_paths": {"workstation": "/srv/hosted-repo"},
})
assert r.status_code == 201
assert r.json()["host_paths"] == {"workstation": "/srv/hosted-repo"}
# ---------------------------------------------------------------------------
# Topic tests
# ---------------------------------------------------------------------------