feat: status page enhancements
This commit is contained in:
parent
158a6ee716
commit
44d353a30f
5 changed files with 561 additions and 14 deletions
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue