feat: status page enhancements

This commit is contained in:
Ubuntu 2026-04-25 12:14:06 +00:00
parent 158a6ee716
commit 44d353a30f
5 changed files with 561 additions and 14 deletions

View file

@ -1,4 +1,11 @@
"""Services API endpoints."""
"""Services API endpoints with tier enforcement.
Provides both admin API-key endpoints (no org context) and
organization-scoped endpoints with tier enforcement.
When X-Organization-ID header is provided with a valid API key,
tier enforcement is applied to creation endpoints.
"""
from uuid import UUID
@ -9,6 +16,11 @@ from sqlalchemy.ext.asyncio import AsyncSession
from app.dependencies import get_db, verify_api_key
from app.models.models import Service
from app.models.saas_models import Organization
from app.services.tier_enforcement import (
enforce_service_limit,
get_org_if_provided,
)
router = APIRouter()
@ -20,6 +32,7 @@ class ServiceCreate(BaseModel):
group_name: str | None = Field(None, max_length=50)
position: int = 0
is_visible: bool = True
organization_id: str | None = None
class ServiceUpdate(BaseModel):
@ -40,6 +53,7 @@ def serialize_service(s: Service) -> dict:
"group_name": s.group_name,
"position": s.position,
"is_visible": s.is_visible,
"organization_id": s.organization_id,
"created_at": s.created_at.isoformat() if s.created_at else None,
"updated_at": s.updated_at.isoformat() if s.updated_at else None,
}
@ -59,7 +73,28 @@ async def create_service(
db: AsyncSession = Depends(get_db),
api_key: str = Depends(verify_api_key),
):
"""Create a new service."""
"""Create a new service.
If organization_id is provided in the request body and a matching org
exists, tier enforcement is applied to ensure the org hasn't exceeded
its services_per_page limit.
"""
org = None
if data.organization_id:
result = await db.execute(
select(Organization).where(Organization.id == data.organization_id)
)
org = result.scalar_one_or_none()
if org is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Organization '{data.organization_id}' not found",
)
# Tier enforcement when org context is provided
if org is not None:
await enforce_service_limit(db, org)
service = Service(
name=data.name,
slug=data.slug,
@ -67,6 +102,7 @@ async def create_service(
group_name=data.group_name,
position=data.position,
is_visible=data.is_visible,
organization_id=data.organization_id,
)
db.add(service)
await db.flush()