feat: status page enhancements
This commit is contained in:
parent
158a6ee716
commit
44d353a30f
5 changed files with 561 additions and 14 deletions
|
|
@ -1,17 +1,29 @@
|
|||
"""Subscribers API endpoints."""
|
||||
"""Subscribers API endpoints with tier enforcement.
|
||||
|
||||
When adding a subscriber to an organization, the org's subscriber limit
|
||||
is checked against the org's tier.
|
||||
"""
|
||||
|
||||
from uuid import UUID
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from pydantic import BaseModel, Field
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.dependencies import get_db, verify_api_key
|
||||
from app.models.models import Subscriber
|
||||
from app.models.saas_models import Organization
|
||||
from app.services.tier_enforcement import enforce_subscriber_limit
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
class SubscriberCreate(BaseModel):
|
||||
email: str = Field(..., max_length=255)
|
||||
organization_id: str | None = None # Optional: for tier enforcement
|
||||
|
||||
|
||||
@router.get("/")
|
||||
async def list_subscribers(db: AsyncSession = Depends(get_db)):
|
||||
"""List all subscribers."""
|
||||
|
|
@ -21,6 +33,7 @@ async def list_subscribers(db: AsyncSession = Depends(get_db)):
|
|||
{
|
||||
"id": s.id,
|
||||
"email": s.email,
|
||||
"organization_id": s.organization_id,
|
||||
"is_confirmed": s.is_confirmed,
|
||||
"created_at": s.created_at.isoformat() if s.created_at else None,
|
||||
}
|
||||
|
|
@ -30,16 +43,36 @@ async def list_subscribers(db: AsyncSession = Depends(get_db)):
|
|||
|
||||
@router.post("/", status_code=status.HTTP_201_CREATED)
|
||||
async def create_subscriber(
|
||||
email: str,
|
||||
data: SubscriberCreate,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
api_key: str = Depends(verify_api_key),
|
||||
):
|
||||
"""Add a new subscriber."""
|
||||
import uuid
|
||||
"""Add a new subscriber.
|
||||
|
||||
If organization_id is provided, tier enforcement is applied to ensure
|
||||
the org hasn't exceeded its subscriber 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_subscriber_limit(db, org)
|
||||
|
||||
import uuid
|
||||
subscriber = Subscriber(
|
||||
email=email,
|
||||
email=data.email,
|
||||
confirm_token=str(uuid.uuid4()),
|
||||
organization_id=data.organization_id,
|
||||
)
|
||||
db.add(subscriber)
|
||||
await db.flush()
|
||||
|
|
@ -47,6 +80,7 @@ async def create_subscriber(
|
|||
return {
|
||||
"id": subscriber.id,
|
||||
"email": subscriber.email,
|
||||
"organization_id": subscriber.organization_id,
|
||||
"confirm_token": subscriber.confirm_token,
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue