Repository navigation
Bug fix/grayjourney #232
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
Open
grayjourney
wants to merge
5
commits into
Base360-AI:main
Choose a base branch
from
grayjourney:bug-fix/grayjourney
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Bug fix/grayjourney #232
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
6449f66
fix(db): connect backend to local Postgres
graytran 07e10ce
fix(revenue): count monthly revenue in property timezone
graytran 97fd4ce
fix(cache): scope revenue cache per tenant
graytran 9f7ccc0
fix(dashboard): show only the tenant's own properties
graytran f7f6e43
fix(revenue): round totals to cents on the backend
graytran File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| from typing import Any, Dict, List | ||
|
|
||
|
|
||
| async def list_properties(tenant_id: str, db_session=None) -> List[Dict[str, Any]]: | ||
| """ | ||
| Returns the properties that belong to one tenant, ordered by id. | ||
| """ | ||
| from sqlalchemy import text | ||
|
|
||
| query = text(""" | ||
| SELECT id, name | ||
| FROM properties | ||
| WHERE tenant_id = :tenant_id | ||
| ORDER BY id | ||
| """) | ||
| params = {"tenant_id": tenant_id} | ||
|
|
||
| if db_session is None: | ||
| from app.core.database_pool import db_pool | ||
|
|
||
| if not db_pool.session_factory: | ||
| await db_pool.initialize() | ||
| async with db_pool.get_session() as session: | ||
| result = await session.execute(query, params) | ||
| rows = result.fetchall() | ||
| else: | ||
| result = await db_session.execute(query, params) | ||
| rows = result.fetchall() | ||
|
|
||
| return [{"id": row.id, "name": row.name} for row in rows] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| import types | ||
|
|
||
| import pytest | ||
| from fastapi.testclient import TestClient | ||
|
|
||
| from app.core.auth import authenticate_request | ||
| from app.main import app | ||
|
|
||
|
|
||
| def get_summary(total: str): | ||
| async def fake_get_revenue_summary(property_id, tenant_id): | ||
| return { | ||
| "property_id": "prop-002", | ||
| "tenant_id": "tenant-a", | ||
| "total": total, | ||
| "currency": "USD", | ||
| "count": 5, | ||
| } | ||
|
|
||
| app.dependency_overrides[authenticate_request] = lambda: types.SimpleNamespace( | ||
| tenant_id="tenant-a" | ||
| ) | ||
| try: | ||
| import app.api.v1.dashboard as dashboard | ||
|
|
||
| original = dashboard.get_revenue_summary | ||
| dashboard.get_revenue_summary = fake_get_revenue_summary | ||
| try: | ||
| return TestClient(app).get("/api/v1/dashboard/summary?property_id=prop-002") | ||
| finally: | ||
| dashboard.get_revenue_summary = original | ||
| finally: | ||
| app.dependency_overrides.clear() | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| "total, expected", | ||
| [ | ||
| ("5095.565", 5095.57), | ||
| ("2250.055", 2250.06), | ||
| ("1.005", 1.01), | ||
| ("2250.000", 2250.0), | ||
| ("4975.5", 4975.5), | ||
| ("0.00", 0.0), | ||
| ], | ||
| ) | ||
| def test_total_revenue_is_rounded_half_up_to_two_decimals(total, expected): | ||
| response = get_summary(total) | ||
| assert response.status_code == 200 | ||
| value = response.json()["total_revenue"] | ||
| assert isinstance(value, (int, float)) and not isinstance(value, bool) | ||
| assert value == expected |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| import asyncio | ||
|
|
||
| from app.core.database_pool import DatabasePool | ||
| from app.services.properties import list_properties | ||
|
|
||
|
|
||
| def properties_for(tenant_id: str): | ||
| async def run(): | ||
| pool = DatabasePool() | ||
| await pool.initialize() | ||
| try: | ||
| async with pool.get_session() as session: | ||
| return await list_properties(tenant_id, db_session=session) | ||
| finally: | ||
| await pool.close() | ||
|
|
||
| return asyncio.run(run()) | ||
|
|
||
|
|
||
| def test_tenant_b_sees_only_its_properties_ordered_by_id(): | ||
| assert properties_for("tenant-b") == [ | ||
| {"id": "prop-001", "name": "Mountain Lodge Beta"}, | ||
| {"id": "prop-004", "name": "Lakeside Cottage"}, | ||
| {"id": "prop-005", "name": "Urban Loft Modern"}, | ||
| ] | ||
|
|
||
|
|
||
| def test_tenant_a_sees_only_its_properties_ordered_by_id(): | ||
| assert properties_for("tenant-a") == [ | ||
| {"id": "prop-001", "name": "Beach House Alpha"}, | ||
| {"id": "prop-002", "name": "City Apartment Downtown"}, | ||
| {"id": "prop-003", "name": "Country Villa Estate"}, | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| import asyncio | ||
| from decimal import Decimal | ||
|
|
||
| from app.core.database_pool import DatabasePool | ||
| from app.services.reservations import calculate_monthly_revenue | ||
|
|
||
|
|
||
| def monthly_revenue(property_id: str, tenant_id: str, month: int, year: int) -> Decimal: | ||
| async def run(): | ||
| pool = DatabasePool() | ||
| await pool.initialize() | ||
| try: | ||
| async with pool.get_session() as session: | ||
| return await calculate_monthly_revenue(property_id, tenant_id, month, year, db_session=session) | ||
| finally: | ||
| await pool.close() | ||
|
|
||
| return asyncio.run(run()) | ||
|
|
||
|
|
||
| def test_march_uses_property_timezone(): | ||
| # res-tz-1 checks in 2024-02-29 23:30 UTC = 2024-03-01 00:30 Europe/Paris | ||
| assert monthly_revenue("prop-001", "tenant-a", 3, 2024) == Decimal("2250.000") | ||
|
|
||
|
|
||
| def test_february_excludes_booking_that_is_march_in_local_time(): | ||
| assert monthly_revenue("prop-001", "tenant-a", 2, 2024) == Decimal("0") | ||
|
|
||
|
|
||
| def test_same_property_id_in_other_tenant_is_not_counted(): | ||
| assert monthly_revenue("prop-001", "tenant-b", 3, 2024) == Decimal("0") | ||
|
|
||
|
|
||
| def test_new_york_property_march_total(): | ||
| assert monthly_revenue("prop-004", "tenant-b", 3, 2024) == Decimal("1776.500") |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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:
calculate_monthly_revenueis not wired into/dashboard/summaryorget_revenue_summary, leaving the timezone fix unreachable by live production requests.Severity: LOW
Suggested Fix
Update
get_revenue_summaryin the dashboard service flow to invokecalculate_monthly_revenueinstead ofcalculate_total_revenuewhen monthly figures and timezone awareness are required.Prompt for AI Agent
Did we get this right? 👍 / 👎 to inform future reviews.