feat: make repository reads alias-aware
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 25s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a049a4-ee9f-78e1-9d66-2cb0f9bea3e3
This commit is contained in:
tegwick 2026-08-29 10:47:51 +02:00
parent 639b9aed08
commit 2e2ae1e5d0
19 changed files with 982 additions and 94 deletions

View file

@ -13,7 +13,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from api.database import get_session
from api.models.managed_repo import ManagedRepo
from api.models.service_catalog import (
ServiceCatalog,
ServiceCloud,
@ -22,6 +21,7 @@ from api.models.service_catalog import (
ServiceThirdParty,
)
from api.schemas.service import ServiceCatalogRead, ServiceUpsert
from api.services.repository_aliases import resolve_repository_slug
router = APIRouter(prefix="/services", tags=["services"])
@ -42,6 +42,7 @@ async def list_services(
development_type: str | None = None,
maturity_level: int | None = None,
status: str | None = None,
repo_slug: str | None = None,
session: AsyncSession = Depends(get_session),
) -> list[ServiceCatalog]:
q = select(ServiceCatalog).options(*_WITH_EXTENSIONS)
@ -53,6 +54,11 @@ async def list_services(
q = q.where(ServiceCatalog.maturity_level == maturity_level)
if status:
q = q.where(ServiceCatalog.status == status)
if repo_slug:
resolution = await resolve_repository_slug(session, repo_slug)
q = q.join(ServiceFirstParty).where(
ServiceFirstParty.repo_id == resolution.repo.id
)
q = q.order_by(ServiceCatalog.name.asc())
result = await session.execute(q)
return list(result.scalars().all())
@ -131,12 +137,10 @@ async def _apply_extensions(svc: ServiceCatalog, body: ServiceUpsert, session: A
if body.first_party is not None:
data = body.first_party.model_dump(exclude={"repo_slug"})
if body.first_party.repo_slug and not data.get("repo_id"):
repo = (await session.execute(
select(ManagedRepo).where(ManagedRepo.slug == body.first_party.repo_slug)
)).scalar_one_or_none()
if repo is None:
raise HTTPException(status_code=404, detail=f"Repo '{body.first_party.repo_slug}' not found")
data["repo_id"] = repo.id
resolution = await resolve_repository_slug(
session, body.first_party.repo_slug
)
data["repo_id"] = resolution.repo.id
await _upsert_ext(ServiceFirstParty, svc.id, data, session)