Skip to content

Commit d20c7f5

Browse files
committed
feat(api): Add /users/usage endpoint (#96)
- Create routes/users.py with usage and limit check endpoints - GET /users/usage - returns tier, repo count, limits - GET /users/limits/check-repo-add - pre-check before adding repo - Register users_router in main.py
1 parent 54042e2 commit d20c7f5

2 files changed

Lines changed: 67 additions & 0 deletions

File tree

backend/main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from routes.search import router as search_router
2626
from routes.analysis import router as analysis_router
2727
from routes.api_keys import router as api_keys_router
28+
from routes.users import router as users_router
2829

2930

3031
# Lifespan context manager for startup/shutdown
@@ -86,6 +87,7 @@ async def dispatch(self, request: Request, call_next):
8687
app.include_router(search_router, prefix=API_PREFIX)
8788
app.include_router(analysis_router, prefix=API_PREFIX)
8889
app.include_router(api_keys_router, prefix=API_PREFIX)
90+
app.include_router(users_router, prefix=API_PREFIX)
8991

9092
# WebSocket endpoint (versioned)
9193
app.add_api_websocket_route(f"{API_PREFIX}/ws/index/{{repo_id}}", websocket_index)

backend/routes/users.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""User routes - profile and usage information."""
2+
from fastapi import APIRouter, Depends
3+
4+
from dependencies import user_limits
5+
from middleware.auth import require_auth, AuthContext
6+
from services.observability import logger
7+
8+
router = APIRouter(prefix="/users", tags=["Users"])
9+
10+
11+
@router.get("/usage")
12+
async def get_user_usage(auth: AuthContext = Depends(require_auth)):
13+
"""
14+
Get current user's usage and limits.
15+
16+
Returns:
17+
- tier: Current subscription tier
18+
- repositories: Current count and limit
19+
- limits: All tier limits
20+
- features: Available features for tier
21+
"""
22+
user_id = auth.user_id
23+
24+
if not user_id:
25+
logger.warning("Usage check without user_id", identifier=auth.identifier)
26+
# Return free tier defaults for API key users
27+
return {
28+
"tier": "free",
29+
"repositories": {
30+
"current": 0,
31+
"limit": 3,
32+
"display": "0/3"
33+
},
34+
"limits": {
35+
"max_files_per_repo": 500,
36+
"max_functions_per_repo": 2000,
37+
"playground_searches_per_day": 50,
38+
},
39+
"features": {
40+
"priority_indexing": False,
41+
"mcp_access": True,
42+
}
43+
}
44+
45+
usage = await user_limits.get_usage_summary(user_id)
46+
logger.info("Usage retrieved", user_id=user_id, tier=usage.get("tier"))
47+
48+
return usage
49+
50+
51+
@router.get("/limits/check-repo-add")
52+
async def check_can_add_repo(auth: AuthContext = Depends(require_auth)):
53+
"""
54+
Check if user can add another repository.
55+
56+
Call this before showing "Add Repository" button to
57+
disable it if limit reached.
58+
"""
59+
user_id = auth.user_id
60+
61+
if not user_id:
62+
return {"allowed": True, "message": "OK"}
63+
64+
result = await user_limits.check_repo_count(user_id)
65+
return result.to_dict()

0 commit comments

Comments
 (0)