feat: add GET /auth/me/feature-flags resolution endpoint

Resolves feature flags for the current user using:
account override > plan default > false

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-04-02 15:16:26 +00:00
parent a2749104f4
commit a60c19b305
2 changed files with 164 additions and 0 deletions

View File

@@ -26,6 +26,7 @@ from app.models.refresh_token import RefreshToken
from app.models.account import Account
from app.models.subscription import Subscription
from app.models.account_invite import AccountInvite
from app.models.feature_flag import FeatureFlag, PlanFeatureDefault, AccountFeatureOverride
from app.schemas.user import UserCreate, UserResponse, UserLogin, UserUpdate
from app.schemas.token import Token
from app.schemas.auth_password import (
@@ -718,3 +719,59 @@ async def verify_email(
await db.commit()
return {"message": "Email verified successfully"}
@router.get("/me/feature-flags")
async def get_my_feature_flags(
current_user: Annotated[User, Depends(get_current_active_user)],
db: Annotated[AsyncSession, Depends(get_db)],
) -> dict[str, bool]:
"""Resolve feature flags for the current user's account and plan."""
plan = "free"
if current_user.account_id:
sub_result = await db.execute(
select(Subscription).where(
Subscription.account_id == current_user.account_id,
Subscription.status.in_(["active", "trialing"]),
)
)
sub = sub_result.scalar_one_or_none()
if sub:
plan = sub.plan
flags_result = await db.execute(select(FeatureFlag))
flags = flags_result.scalars().all()
if not flags:
return {}
flag_ids = [f.id for f in flags]
defaults_result = await db.execute(
select(PlanFeatureDefault).where(
PlanFeatureDefault.flag_id.in_(flag_ids),
PlanFeatureDefault.plan == plan,
)
)
plan_defaults = {d.flag_id: d.enabled for d in defaults_result.scalars().all()}
overrides: dict = {}
if current_user.account_id:
overrides_result = await db.execute(
select(AccountFeatureOverride).where(
AccountFeatureOverride.flag_id.in_(flag_ids),
AccountFeatureOverride.account_id == current_user.account_id,
)
)
overrides = {o.flag_id: o.enabled for o in overrides_result.scalars().all()}
resolved = {}
for flag in flags:
if flag.id in overrides:
resolved[flag.flag_key] = overrides[flag.id]
elif flag.id in plan_defaults:
resolved[flag.flag_key] = plan_defaults[flag.id]
else:
resolved[flag.flag_key] = False
return resolved