Repository navigation
PropertyFlow: Flex Technical Assessment #219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
2b8a523
2873c6a
796991d
5566a7d
846ce01
71e38ee
f9066c8
6053d2a
d75a57c
8b21d64
7818d12
789ba87
58e1935
4653a23
1288bc1
fe74418
4e84787
8ee2d6b
5fbed72
75577d0
4a079dd
e89e93f
2f417f8
f3b20e4
0754de4
242d825
eacf0ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # Python | ||
| __pycache__/ | ||
| *.py[cod] | ||
| .venv/ | ||
| .pytest_cache/ | ||
|
|
||
| # Node | ||
| node_modules/ | ||
|
|
||
| # Env | ||
| .env.local | ||
| .env.*.local | ||
|
|
||
| # OS / editor | ||
| .DS_Store | ||
| *.log | ||
| vite.config.ts.timestamp-*.mjs | ||
|
|
||
| # Build output | ||
| frontend/dist/ | ||
|
|
||
| # Local env (see frontend/.env.example) | ||
| .env |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,25 +1,59 @@ | ||
| from fastapi import APIRouter, Depends, HTTPException | ||
| from typing import Dict, Any | ||
| from fastapi import APIRouter, Depends, HTTPException, Query | ||
| from typing import Dict, Any, List, Optional | ||
| from app.services.cache import get_revenue_summary | ||
| from app.core.auth import authenticate_request as get_current_user | ||
|
|
||
| router = APIRouter() | ||
|
|
||
|
|
||
| def _require_tenant(current_user) -> str: | ||
| tenant_id = getattr(current_user, "tenant_id", None) | ||
| if not tenant_id: | ||
| raise HTTPException(status_code=403, detail="User is not assigned to a tenant") | ||
| return tenant_id | ||
|
|
||
|
|
||
| @router.get("/dashboard/properties") | ||
| async def get_dashboard_properties(current_user: dict = Depends(get_current_user)) -> List[Dict[str, str]]: | ||
| tenant_id = _require_tenant(current_user) | ||
|
|
||
| from app.core.database_pool import db_pool | ||
| from sqlalchemy import text | ||
|
|
||
| try: | ||
| await db_pool.initialize() | ||
| async with db_pool.get_session() as session: | ||
| result = await session.execute( | ||
| text("SELECT id, name FROM properties WHERE tenant_id = :tenant_id ORDER BY id"), | ||
| {"tenant_id": tenant_id}, | ||
| ) | ||
| return [{"id": row.id, "name": row.name} for row in result] | ||
| except Exception: | ||
| raise HTTPException(status_code=503, detail="Properties are temporarily unavailable") | ||
|
|
||
|
|
||
| @router.get("/dashboard/summary") | ||
| async def get_dashboard_summary( | ||
| property_id: str, | ||
| month: Optional[int] = Query(None, ge=1, le=12), | ||
| year: Optional[int] = Query(None, ge=2000, le=2100), | ||
| current_user: dict = Depends(get_current_user) | ||
| ) -> Dict[str, Any]: | ||
|
|
||
| tenant_id = getattr(current_user, "tenant_id", "default_tenant") or "default_tenant" | ||
|
|
||
| revenue_data = await get_revenue_summary(property_id, tenant_id) | ||
|
|
||
| total_revenue_float = float(revenue_data['total']) | ||
| tenant_id = _require_tenant(current_user) | ||
|
|
||
| if (month is None) != (year is None): | ||
| raise HTTPException(status_code=400, detail="month and year must be provided together") | ||
|
|
||
| try: | ||
| revenue_data = await get_revenue_summary(property_id, tenant_id, month, year) | ||
| except Exception: | ||
| raise HTTPException(status_code=503, detail="Revenue data is temporarily unavailable") | ||
|
|
||
| return { | ||
| "property_id": revenue_data['property_id'], | ||
| "total_revenue": total_revenue_float, | ||
| # Sent as a decimal string; floats lose cents. | ||
| "total_revenue": revenue_data['total'], | ||
| "currency": revenue_data['currency'], | ||
| "reservations_count": revenue_data['count'] | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: The new tenant resolver only works for test emails, causing the auth cache to be invalidated on every request for real users, forcing a re-authentication loop.
Severity: CRITICAL
Suggested Fix
Update
tenant_resolver.pyto correctly resolve tenant IDs for all production users, not just the hardcoded test emails. This likely involves restoring the previous logic or implementing a proper lookup based on the user's email or other attributes from the database.Prompt for AI Agent
Did we get this right? 👍 / 👎 to inform future reviews.