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, slug=body.slug,
name=body.name, name=body.name,
local_path=body.local_path, local_path=body.local_path,
host_paths=body.host_paths,
remote_url=body.remote_url, remote_url=body.remote_url,
git_fingerprint=body.git_fingerprint, git_fingerprint=body.git_fingerprint,
description=body.description, description=body.description,

View File

@@ -3,41 +3,13 @@ from datetime import datetime
from pydantic import BaseModel, ConfigDict from pydantic import BaseModel, ConfigDict
from hub_core.schemas.capability import (
# --------------------------------------------------------------------------- CapabilityRequestDispute,
# Capability Catalog schemas CapabilityRequestStatusPatch,
# --------------------------------------------------------------------------- CatalogCreate,
CatalogPatch,
class CatalogCreate(BaseModel): CatalogRead,
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
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@@ -60,11 +32,6 @@ class CapabilityRequestAccept(BaseModel):
fulfilling_workstream_id: uuid.UUID | None = None 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): class CapabilityRequestPatch(BaseModel):
catalog_entry_id: uuid.UUID | None = None catalog_entry_id: uuid.UUID | None = None
priority: str | None = None priority: str | None = None
@@ -72,12 +39,6 @@ class CapabilityRequestPatch(BaseModel):
fulfilling_workstream_id: uuid.UUID | None = None fulfilling_workstream_id: uuid.UUID | None = None
class CapabilityRequestDispute(BaseModel):
reason: str
disputed_by: str
suggested_domain: str | None = None
class CapabilityRequestReroute(BaseModel): class CapabilityRequestReroute(BaseModel):
note: str note: str
rerouted_by: str rerouted_by: str

View File

@@ -2,17 +2,16 @@ import uuid
from datetime import date, datetime from datetime import date, datetime
from typing import Any, Literal 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): class RepoCreate(CoreRepoCreate):
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
topic_id: uuid.UUID | None = None topic_id: uuid.UUID | None = None
@@ -26,12 +25,6 @@ class RepoUpdate(BaseModel):
last_state_synced_at: datetime | None = None 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): class RepoOnboardRequest(BaseModel):
"""Start scripted onboarding for a working copy that is visible to State Hub.""" """Start scripted onboarding for a working copy that is visible to State Hub."""
domain_slug: str domain_slug: str
@@ -49,19 +42,7 @@ class RepoOnboardResult(BaseModel):
stderr: str = "" stderr: str = ""
class RepoRead(BaseModel): class RepoRead(CoreRepoRead):
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
topic_id: uuid.UUID | None = None topic_id: uuid.UUID | None = None
sbom_source: str | None = None sbom_source: str | None = None
last_sbom_at: datetime | None = None last_sbom_at: datetime | None = None

View File

@@ -1,8 +1,23 @@
from api.schemas.agent_message import MessageCreate 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.doi import DoIReport
from api.schemas.domain import DomainCreate, DomainRead, DomainRename, DomainUpdate 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 api.schemas.tpsc import GDPR_WARNING_LEVELS, TPSCCatalogRead, TPSCGDPRReport
from hub_core.schemas.agent_message import MessageCreate as CoreMessageCreate 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.doi import DoIReport as CoreDoIReport
from hub_core.schemas.domain import ( from hub_core.schemas.domain import (
DomainCreate as CoreDomainCreate, DomainCreate as CoreDomainCreate,
@@ -10,6 +25,11 @@ from hub_core.schemas.domain import (
DomainRename as CoreDomainRename, DomainRename as CoreDomainRename,
DomainUpdate as CoreDomainUpdate, 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 ( from hub_core.schemas.tpsc import (
GDPR_WARNING_LEVELS as CORE_GDPR_WARNING_LEVELS, GDPR_WARNING_LEVELS as CORE_GDPR_WARNING_LEVELS,
TPSCCatalogRead as CoreTPSCCatalogRead, TPSCCatalogRead as CoreTPSCCatalogRead,
@@ -32,6 +52,25 @@ def test_state_hub_reexports_core_domain_base_schemas() -> None:
assert DomainUpdate is CoreDomainUpdate 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: def test_state_hub_reexports_core_tpsc_schemas() -> None:
assert TPSCCatalogRead is CoreTPSCCatalogRead assert TPSCCatalogRead is CoreTPSCCatalogRead
assert TPSCGDPRReport is CoreTPSCGDPRReport assert TPSCGDPRReport is CoreTPSCGDPRReport

View File

@@ -75,6 +75,23 @@ class TestDomains:
assert r.status_code == 409 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 # Topic tests
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------