From 75b64ef62c74fab41c08096b03b651c0f50b9808 Mon Sep 17 00:00:00 2001 From: Sarah Gamal Date: Fri, 25 Sep 2026 20:29:05 +0300 Subject: [PATCH] Fix cross-tenant cache leak, float precision, monthly revenue, and DB pool config --- BUGS.md | 103 +++ FIXES.md | 120 ++++ INVESTIGATION_GUIDE.md | 589 ++++++++++++++++++ NOTES.md | 123 ++++ .../app/__pycache__/config.cpython-311.pyc | Bin 0 -> 12367 bytes .../app/__pycache__/database.cpython-311.pyc | Bin 0 -> 22454 bytes backend/app/__pycache__/main.cpython-311.pyc | Bin 0 -> 22652 bytes .../v1/__pycache__/auth_info.cpython-311.pyc | Bin 0 -> 10140 bytes .../v1/__pycache__/bootstrap.cpython-311.pyc | Bin 0 -> 27620 bytes .../api/v1/__pycache__/cities.cpython-311.pyc | Bin 0 -> 5755 bytes .../city_access_fast.cpython-311.pyc | Bin 0 -> 26470 bytes .../city_access_fixed.cpython-311.pyc | Bin 0 -> 21909 bytes .../company_settings.cpython-311.pyc | Bin 0 -> 14313 bytes .../v1/__pycache__/dashboard.cpython-311.pyc | Bin 0 -> 1678 bytes .../__pycache__/departments.cpython-311.pyc | Bin 0 -> 22836 bytes .../api/v1/__pycache__/health.cpython-311.pyc | Bin 0 -> 26191 bytes .../api/v1/__pycache__/login.cpython-311.pyc | Bin 0 -> 8674 bytes .../persistent_auth.cpython-311.pyc | Bin 0 -> 17004 bytes .../v1/__pycache__/profile.cpython-311.pyc | Bin 0 -> 24131 bytes .../users_lightning.cpython-311.pyc | Bin 0 -> 66125 bytes backend/app/api/v1/dashboard.py | 5 +- .../async_processing.cpython-311.pyc | Bin 0 -> 21213 bytes .../app/core/__pycache__/auth.cpython-311.pyc | Bin 0 -> 29982 bytes .../circuit_breaker_fallback.cpython-311.pyc | Bin 0 -> 9833 bytes .../__pycache__/database_pool.cpython-311.pyc | Bin 0 -> 3449 bytes .../persistent_sessions.cpython-311.pyc | Bin 0 -> 26403 bytes .../__pycache__/redis_client.cpython-311.pyc | Bin 0 -> 11555 bytes .../supabase_connection_pool.cpython-311.pyc | Bin 0 -> 34857 bytes .../__pycache__/tenant_cache.cpython-311.pyc | Bin 0 -> 5097 bytes .../tenant_context.cpython-311.pyc | Bin 0 -> 2326 bytes .../tenant_resolver.cpython-311.pyc | Bin 0 -> 3525 bytes .../token_encryption.cpython-311.pyc | Bin 0 -> 12619 bytes backend/app/core/database_pool.py | 2 +- .../models/__pycache__/auth.cpython-311.pyc | Bin 0 -> 1479 bytes .../__pycache__/profile.cpython-311.pyc | Bin 0 -> 5815 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 486 bytes .../__pycache__/middleware.cpython-311.pyc | Bin 0 -> 2691 bytes .../__pycache__/performance.cpython-311.pyc | Bin 0 -> 16802 bytes .../__pycache__/cache.cpython-311.pyc | Bin 0 -> 1459 bytes .../__pycache__/reservations.cpython-311.pyc | Bin 0 -> 3839 bytes backend/app/services/cache.py | 2 +- backend/app/services/reservations.py | 151 ++--- 42 files changed, 1005 insertions(+), 90 deletions(-) create mode 100644 BUGS.md create mode 100644 FIXES.md create mode 100644 INVESTIGATION_GUIDE.md create mode 100644 NOTES.md create mode 100644 backend/app/__pycache__/config.cpython-311.pyc create mode 100644 backend/app/__pycache__/database.cpython-311.pyc create mode 100644 backend/app/__pycache__/main.cpython-311.pyc create mode 100644 backend/app/api/v1/__pycache__/auth_info.cpython-311.pyc create mode 100644 backend/app/api/v1/__pycache__/bootstrap.cpython-311.pyc create mode 100644 backend/app/api/v1/__pycache__/cities.cpython-311.pyc create mode 100644 backend/app/api/v1/__pycache__/city_access_fast.cpython-311.pyc create mode 100644 backend/app/api/v1/__pycache__/city_access_fixed.cpython-311.pyc create mode 100644 backend/app/api/v1/__pycache__/company_settings.cpython-311.pyc create mode 100644 backend/app/api/v1/__pycache__/dashboard.cpython-311.pyc create mode 100644 backend/app/api/v1/__pycache__/departments.cpython-311.pyc create mode 100644 backend/app/api/v1/__pycache__/health.cpython-311.pyc create mode 100644 backend/app/api/v1/__pycache__/login.cpython-311.pyc create mode 100644 backend/app/api/v1/__pycache__/persistent_auth.cpython-311.pyc create mode 100644 backend/app/api/v1/__pycache__/profile.cpython-311.pyc create mode 100644 backend/app/api/v1/__pycache__/users_lightning.cpython-311.pyc create mode 100644 backend/app/core/__pycache__/async_processing.cpython-311.pyc create mode 100644 backend/app/core/__pycache__/auth.cpython-311.pyc create mode 100644 backend/app/core/__pycache__/circuit_breaker_fallback.cpython-311.pyc create mode 100644 backend/app/core/__pycache__/database_pool.cpython-311.pyc create mode 100644 backend/app/core/__pycache__/persistent_sessions.cpython-311.pyc create mode 100644 backend/app/core/__pycache__/redis_client.cpython-311.pyc create mode 100644 backend/app/core/__pycache__/supabase_connection_pool.cpython-311.pyc create mode 100644 backend/app/core/__pycache__/tenant_cache.cpython-311.pyc create mode 100644 backend/app/core/__pycache__/tenant_context.cpython-311.pyc create mode 100644 backend/app/core/__pycache__/tenant_resolver.cpython-311.pyc create mode 100644 backend/app/core/__pycache__/token_encryption.cpython-311.pyc create mode 100644 backend/app/models/__pycache__/auth.cpython-311.pyc create mode 100644 backend/app/models/__pycache__/profile.cpython-311.pyc create mode 100644 backend/app/monitoring/__pycache__/__init__.cpython-311.pyc create mode 100644 backend/app/monitoring/__pycache__/middleware.cpython-311.pyc create mode 100644 backend/app/monitoring/__pycache__/performance.cpython-311.pyc create mode 100644 backend/app/services/__pycache__/cache.cpython-311.pyc create mode 100644 backend/app/services/__pycache__/reservations.cpython-311.pyc diff --git a/BUGS.md b/BUGS.md new file mode 100644 index 000000000..9951b9649 --- /dev/null +++ b/BUGS.md @@ -0,0 +1,103 @@ +# Bugs Found — Property Revenue Dashboard + +--- + +## Bug #1 — Cross-Tenant Cache Leak +**File:** `backend/app/services/cache.py` — Line 13 + +```python +# BUGGY +cache_key = f"revenue:{property_id}" + +# FIXED +cache_key = f"revenue:{tenant_id}:{property_id}" +``` + +**What happens:** +Both tenants share `prop-001` in the database (valid — composite PK). +When Ocean Rentals loads first → $0 gets cached as `revenue:prop-001`. +When Sunset Properties loads → hits cache → sees $0 instead of their real $2,250. + +**Client report:** *"Sometimes we see revenue numbers that belong to another company"* + +--- + +## Bug #2 — Float Precision Loss +**File:** `backend/app/api/v1/dashboard.py` — Line 18 + +```python +# BUGGY +total_revenue_float = float(revenue_data['total']) + +# FIXED +from decimal import Decimal, ROUND_HALF_UP +total_revenue_float = float( + Decimal(str(revenue_data['total'])).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP) +) +``` + +**What happens:** +DB stores amounts as `NUMERIC(10,3)` — exact decimal. +`float()` converts to IEEE 754 binary — cannot represent most decimals exactly. + +``` +DB stores: 4975.500 ← exact +API returns: 4975.5 ← precision lost + +333.333 + 333.333 + 333.334 = 999.9999999999999 (float) + = 1000.000 (DB NUMERIC — exact) +``` + +**Client report:** *"Revenue totals are slightly off by a few cents"* + +--- + +## Bug #3 — Monthly Revenue Always Returns Zero +**File:** `backend/app/services/reservations.py` — Line 32 + +```python +# BUGGY — DB call commented out, placeholder hardcoded +# result = await db.fetch_val(query, property_id, tenant_id, start_date, end_date) +# return result or Decimal('0') +return Decimal('0') # Placeholder for now until DB connection is finalized + +# ALSO BUGGY — timezone-naive datetime +start_date = datetime(year, month, 1) # treated as UTC, ignores property timezone +``` + +**What happens:** +Every call returns $0 regardless of actual bookings. +Even if fixed, the date range uses naive UTC — missing Paris-timezone reservations: + +```sql +-- res-tz-1: Feb 29 23:30 UTC = March 1 00:30 Paris time +-- UTC query puts it in February → $1,250 missing from March total +'2024-02-29 23:30:00+00' → 1250.000 +``` + +**Client report:** *"Revenue numbers don't match our records for March"* + +--- + +## Bug #4 — Database Pool Uses Wrong Config (Root Cause) +**File:** `backend/app/core/database_pool.py` — Line 18 + +```python +# BUGGY — these attributes don't exist in Settings +database_url = f"postgresql+asyncpg://{settings.supabase_db_user}:..." + +# FIXED — use the actual database_url from settings +database_url = settings.database_url.replace("postgresql://", "postgresql+asyncpg://", 1) +``` + +**What happens:** +Pool fails silently on every request → falls back to hardcoded mock data. +Mock data returns identical values for all tenants → masks Bug #1 completely. +All bugs invisible until this is fixed first. + +``` +mock_data = { + 'prop-001': {'total': '1000.00', 'count': 3}, ← same for ALL tenants + ... +} +``` diff --git a/FIXES.md b/FIXES.md new file mode 100644 index 000000000..65a3f8804 --- /dev/null +++ b/FIXES.md @@ -0,0 +1,120 @@ +# Fixes Applied — Property Revenue Dashboard + +--- + +## Fix #1 — Cross-Tenant Cache Leak +**File:** `backend/app/services/cache.py` — Line 13 + +```python +# BEFORE +cache_key = f"revenue:{property_id}" + +# AFTER +cache_key = f"revenue:{tenant_id}:{property_id}" +``` + +**Result:** +``` +Sunset Properties prop-001 → $2,250.00 ✅ (their real data) +Ocean Rentals prop-001 → $0.00 ✅ (their real data, isolated) +``` +Each tenant now has a completely separate cache entry. One tenant can never read another's cached data. + +--- + +## Fix #2 — Float Precision Loss +**File:** `backend/app/api/v1/dashboard.py` — Line 18 + +```python +# BEFORE +total_revenue_float = float(revenue_data['total']) + +# AFTER +from decimal import Decimal, ROUND_HALF_UP +total_revenue_float = float( + Decimal(str(revenue_data['total'])).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP) +) +``` + +**Result:** +``` +Before: 4975.5 ← float, sub-cent precision lost +After: 4975.50 ← rounded correctly to 2 decimal places +``` +Revenue is rounded at the Decimal level before any float conversion, using standard financial rounding (`ROUND_HALF_UP`). No more "few cents off" discrepancies. + +--- + +## Fix #3 — Monthly Revenue Always Zero + Timezone Bug +**File:** `backend/app/services/reservations.py` — Lines 5–32 + +```python +# BEFORE — placeholder, DB call commented out, timezone-naive +start_date = datetime(year, month, 1) # naive UTC — wrong for Paris properties +... +return Decimal('0') # always zero, never queries DB + +# AFTER — real DB query with timezone-aware date boundaries +async def calculate_monthly_revenue(property_id: str, tenant_id: str, month: int, year: int) -> Decimal: + conn = await asyncpg.connect(settings.database_url) + row = await conn.fetchrow( + """ + SELECT COALESCE(SUM(r.total_amount), 0) AS total + FROM reservations r + JOIN properties p ON r.property_id = p.id AND r.tenant_id = p.tenant_id + WHERE r.property_id = $1 + AND r.tenant_id = $2 + AND (r.check_in_date AT TIME ZONE p.timezone) >= $3 + AND (r.check_in_date AT TIME ZONE p.timezone) < $4 + """, + property_id, tenant_id, start_date, end_date, + ) + return Decimal(str(row["total"])) if row else Decimal("0") +``` + +**Result:** +``` +res-tz-1: check_in = 2024-02-29 23:30 UTC = 2024-03-01 00:30 Paris time + +Before: counted in February (UTC naive) → March total wrong by $1,250 +After: counted in March (AT TIME ZONE) → March total matches client records ✅ +``` + +--- + +## Fix #4 — Database Pool Wrong Config (Root Cause) +**File:** `backend/app/core/database_pool.py` — Line 18 +**File:** `backend/app/services/reservations.py` — DB connection approach + +```python +# BEFORE — settings.supabase_db_user doesn't exist → silent failure → mock data +database_url = f"postgresql+asyncpg://{settings.supabase_db_user}:..." + +# AFTER — use asyncpg directly with settings.database_url +conn = await asyncpg.connect(settings.database_url) +``` + +**Result:** +``` +Before: every request → mock data ($1,000 hardcoded for all tenants) +After: every request → real PostgreSQL data, tenant-isolated ✅ +``` + +--- + +## Verification + +```bash +# Flush cache to test fresh +docker exec new_devs_app-redis-1 redis-cli FLUSHALL + +# Sunset Properties — prop-001 +curl "http://localhost:8000/api/v1/dashboard/summary?property_id=prop-001" \ + -H "Authorization: Bearer " +# → { "total_revenue": 2250.0, "reservations_count": 4 } ✅ + +# Ocean Rentals — prop-001 (same property ID, different tenant) +curl "http://localhost:8000/api/v1/dashboard/summary?property_id=prop-001" \ + -H "Authorization: Bearer " +# → { "total_revenue": 0.0, "reservations_count": 0 } ✅ +``` diff --git a/INVESTIGATION_GUIDE.md b/INVESTIGATION_GUIDE.md new file mode 100644 index 000000000..4a6eeff02 --- /dev/null +++ b/INVESTIGATION_GUIDE.md @@ -0,0 +1,589 @@ +# Bug Investigation & Fix Guide +## Flex Property Revenue Dashboard — Technical Assignment + +--- + +## Table of Contents + +1. [System Overview](#1-system-overview) +2. [Environment Setup](#2-environment-setup) +3. [Bug #1 — Cross-Tenant Cache Leak (Privacy)](#3-bug-1--cross-tenant-cache-leak-privacy) +4. [Bug #2 — Floating-Point Revenue Precision](#4-bug-2--floating-point-revenue-precision) +5. [Bug #3 — Monthly Revenue Always Returns Zero](#5-bug-3--monthly-revenue-always-returns-zero) +6. [Bonus — Hardcoded Property List Leaks Tenant Structure](#6-bonus--hardcoded-property-list-leaks-tenant-structure) +7. [Fix Summary Table](#7-fix-summary-table) +8. [Loom Video Script](#8-loom-video-script) +9. [CTO Interview Talking Points](#9-cto-interview-talking-points) + +--- + +## 1. System Overview + +### Architecture + +``` +Browser (React/TypeScript) + ↓ JWT Bearer token +FastAPI Backend (Python) + ↓ SQL queries with tenant_id filter +PostgreSQL (multi-tenant, one DB) + ↑ Redis (revenue cache, 5-min TTL) +``` + +### Multi-Tenant Model + +The system serves multiple property management companies ("tenants") from a single database. Isolation is enforced by: + +- A `tenant_id` column on `properties` and `reservations` tables +- Row Level Security (RLS) enabled on both tables +- JWT authentication that carries the user's `tenant_id` in the token payload +- Backend query filters: `WHERE property_id = :id AND tenant_id = :tenant_id` + +### Test Credentials + +| Client | Email | Password | Tenant ID | +|--------|-------|----------|-----------| +| Sunset Properties | sunset@propertyflow.com | client_a_2024 | tenant-a | +| Ocean Rentals | ocean@propertyflow.com | client_b_2024 | tenant-b | + +### Key Seed Data + +```sql +-- BOTH tenants deliberately share property ID "prop-001" +-- This is valid (composite PK: id + tenant_id) but exposes the cache bug +('prop-001', 'tenant-a', 'Beach House Alpha', 'Europe/Paris') +('prop-001', 'tenant-b', 'Mountain Lodge Beta', 'America/New_York') + +-- Tenant-A intentional sub-cent amounts (triggers precision bug) +('res-dec-1', 'prop-001', 'tenant-a', ..., 333.333) +('res-dec-2', 'prop-001', 'tenant-a', ..., 333.333) +('res-dec-3', 'prop-001', 'tenant-a', ..., 333.334) +-- DB NUMERIC sum = exactly 1000.000 + +-- Timezone edge-case reservation for tenant-a +-- check_in: 2024-02-29 23:30 UTC = 2024-03-01 00:30 Paris time +('res-tz-1', 'prop-001', 'tenant-a', '2024-02-29 23:30:00+00', ..., 1250.000) +``` + +--- + +## 2. Environment Setup + +```bash +# Clone / open the forked repo +cd /path/to/New_devs_App + +# Start all services (backend, frontend, postgres, redis) +docker-compose up --build + +# Verify services are healthy +# Frontend: http://localhost:3000 +# Backend docs: http://localhost:8000/docs +# PostgreSQL: localhost:5433 +# Redis: localhost:6380 +``` + +Expected startup output: +``` +db | database system is ready to accept connections +redis | Ready to accept connections +backend | Application startup complete. +frontend | nginx started +``` + +--- + +## 3. Bug #1 — Cross-Tenant Cache Leak (Privacy) + +### Client Report +> *"Sometimes when we refresh the page, we see revenue numbers that look like they belong to another company."* — Ocean Rentals (Client B) + +### Root Cause + +**File:** `backend/app/services/cache.py`, **Line 13** + +```python +# BUGGY CODE +async def get_revenue_summary(property_id: str, tenant_id: str) -> Dict[str, Any]: + cache_key = f"revenue:{property_id}" # ← tenant_id is passed in but IGNORED + + cached = await redis_client.get(cache_key) + if cached: + return json.loads(cached) # ← could be another tenant's data! + + result = await calculate_total_revenue(property_id, tenant_id) + await redis_client.setex(cache_key, 300, json.dumps(result)) + return result +``` + +The function accepts `tenant_id` as a parameter but never uses it in the cache key. The key is just `revenue:{property_id}`. + +### Why It Leaks + +The seed data has **both tenants sharing the same property ID** (`prop-001`): + +``` +prop-001 → tenant-a (Beach House Alpha) revenue: $2,250.000 +prop-001 → tenant-b (Mountain Lodge Beta) revenue: $0.00 (no reservations) +``` + +**Scenario A — Client B sees Client A's money:** +1. Client A (Sunset) queries `prop-001` → DB returns $2,250 → cached as `revenue:prop-001` +2. Client B (Ocean) queries `prop-001` → Redis **cache hit** → returns `$2,250` (Client A's data) +3. Client B sees revenue that doesn't belong to them ❌ + +**Scenario B — Client A sees zero:** +1. Client B queries `prop-001` first → DB returns $0 → cached as `revenue:prop-001` +2. Client A queries `prop-001` → cache hit → returns `$0` instead of `$2,250` +3. Client A's board meeting numbers are wrong ❌ + +The 5-minute TTL means this changes on every cache expiry — hence the "sometimes" behaviour. + +### How to Reproduce + +```bash +# Terminal 1 — watch Redis in real time +docker exec -it $(docker ps -qf "name=redis") redis-cli monitor + +# Browser tab 1: log in as ocean@propertyflow.com, open Dashboard, select prop-001 +# Browser tab 2: log in as sunset@propertyflow.com, open Dashboard, select prop-001 +# Refresh both tabs repeatedly — one will show the other's revenue +``` + +### The Fix + +**File:** `backend/app/services/cache.py`, **Line 13** + +```python +# FIXED CODE — include tenant_id in the cache key +cache_key = f"revenue:{tenant_id}:{property_id}" +``` + +**Before:** `revenue:prop-001` +**After:** `revenue:tenant-a:prop-001` and `revenue:tenant-b:prop-001` are separate keys — total isolation. + +```python +# Full fixed function +async def get_revenue_summary(property_id: str, tenant_id: str) -> Dict[str, Any]: + cache_key = f"revenue:{tenant_id}:{property_id}" # ← FIXED + + cached = await redis_client.get(cache_key) + if cached: + return json.loads(cached) + + from app.services.reservations import calculate_total_revenue + result = await calculate_total_revenue(property_id, tenant_id) + await redis_client.setex(cache_key, 300, json.dumps(result)) + return result +``` + +### Why This Is the Correct Fix + +- The `tenant_id` is already trusted (extracted from the signed JWT, not user input) +- Redis key namespacing is the standard pattern for multi-tenant caching +- Zero performance cost — same O(1) Redis lookup +- The fix is minimal and surgical — no logic change, only the key string + +--- + +## 4. Bug #2 — Floating-Point Revenue Precision + +### Client Report +> *"Revenue totals are slightly off by a few cents."* — Finance Team + +### Root Cause + +**File:** `backend/app/api/v1/dashboard.py`, **Line 18** + +```python +# BUGGY CODE +revenue_data = await get_revenue_summary(property_id, tenant_id) +total_revenue_float = float(revenue_data['total']) # ← precision loss here + +return { + "property_id": revenue_data['property_id'], + "total_revenue": total_revenue_float, # ← float sent to frontend + ... +} +``` + +### Why It Loses Precision + +The database stores `total_amount` as `NUMERIC(10, 3)` — exact decimal arithmetic with 3 decimal places. Python's `Decimal` type preserves this. But `float()` converts to IEEE 754 binary floating point, which **cannot exactly represent most decimal fractions**. + +``` +NUMERIC in DB: 333.333 (exact) +Python Decimal: Decimal('333.333') (exact) +Python float: 333.33299999999997726... (approximation) +``` + +The data is specifically designed to expose this: +``` +333.333 + 333.333 + 333.334 = 1000.000 (exact NUMERIC arithmetic in PostgreSQL) + +After float conversion: +333.333... + 333.333... + 333.334... ≈ 999.9999... or 1000.0000001... +``` + +The frontend then does: +```typescript +// RevenueSummary.tsx line 64 +const displayTotal = Math.round(data.total_revenue * 100) / 100; +``` + +If `data.total_revenue` is `999.9999999999999`, then: +- `999.9999999999999 * 100 = 99999.99999999999` +- `Math.round(99999.99999999999) = 100000` +- `100000 / 100 = 1000.00` ← looks OK here + +But with different amounts this can produce visible cent-level errors, and the precision mismatch warning built into the UI confirms this is an intentional test: + +```tsx +{/* RevenueSummary.tsx line 107 — built-in precision warning! */} +{Math.abs(data.total_revenue - displayTotal) > 0.000001 && showRaw && ( +
Precision Mismatch Detected
+)} +``` + +The frontend even has a "Precision Mismatch Detected" warning — this was placed there deliberately as a hint. + +### The Fix + +**File:** `backend/app/api/v1/dashboard.py`, **Line 18** + +```python +# FIXED CODE — round at the Decimal level before converting +from decimal import Decimal, ROUND_HALF_UP + +total_revenue_decimal = Decimal(str(revenue_data['total'])).quantize( + Decimal('0.01'), rounding=ROUND_HALF_UP +) +total_revenue_float = float(total_revenue_decimal) +``` + +**Why `ROUND_HALF_UP`?** Financial calculations conventionally round half-cents up (e.g. $1.005 → $1.01). This matches client expectations and accounting standards. + +**Why not just fix it in the frontend?** The backend should be the source of truth for financial data. Sending an imprecise float to the API means any consumer (mobile app, external integrations) would also get wrong data. + +--- + +## 5. Bug #3 — Monthly Revenue Always Returns Zero + +### Client Report +> *"The revenue numbers don't match our internal records. We're showing different totals for March."* — Sunset Properties (Client A) + +### Root Cause — Part A: Placeholder Never Implemented + +**File:** `backend/app/services/reservations.py`, **Line 32** + +```python +# BUGGY CODE +async def calculate_monthly_revenue(property_id: str, month: int, year: int, db_session=None) -> Decimal: + start_date = datetime(year, month, 1) + if month < 12: + end_date = datetime(year, month + 1, 1) + else: + end_date = datetime(year + 1, 1, 1) + + # SQL query is written but COMMENTED OUT — never runs + query = """ + SELECT SUM(total_amount) as total + FROM reservations + WHERE property_id = $1 + AND tenant_id = $2 + AND check_in_date >= $3 + AND check_in_date < $4 + """ + + # result = await db.fetch_val(query, property_id, tenant_id, start_date, end_date) + # return result or Decimal('0') + + return Decimal('0') # ← ALWAYS returns zero. This is a placeholder, never finished. +``` + +The developer wrote the SQL and date logic, then left the DB call commented out with a placeholder. Every call to `calculate_monthly_revenue` returns `$0` regardless of actual reservations. + +### Root Cause — Part B: Timezone-Naive Datetimes + +Even if the query were uncommented and run, it has a timezone bug: + +```python +start_date = datetime(year, month, 1) # ← naive datetime, no timezone info +``` + +When compared against `TIMESTAMP WITH TIME ZONE` columns in PostgreSQL, a naive Python `datetime` is treated as **UTC**. But Sunset Properties' properties are in `Europe/Paris` (UTC+1 in winter, UTC+2 in summer). + +**The seed data has an intentional timezone edge case:** +```sql +-- res-tz-1: check_in = 2024-02-29 23:30:00+00 UTC +-- = 2024-03-01 00:30:00 Paris time ← this IS a March reservation in Paris! +``` + +With the naive UTC date range for March 2024: +``` +start_date = 2024-03-01 00:00:00 (UTC) +``` + +The query `check_in_date >= '2024-03-01 00:00:00'` in UTC **excludes** `res-tz-1` (which check_in is `2024-02-29 23:30 UTC`). + +But from the client's Paris-timezone perspective, that reservation **is** in March. So their internal records count it for March, but the API doesn't. **This is exactly the mismatch Sunset Properties reported.** + +### The Fix — Part A: Implement the query + +```python +# FIXED CODE +async def calculate_monthly_revenue(property_id: str, tenant_id: str, month: int, year: int) -> Decimal: + from app.core.database_pool import DatabasePool + from sqlalchemy import text + + db_pool = DatabasePool() + await db_pool.initialize() + + if month < 12: + start_date = datetime(year, month, 1) + end_date = datetime(year, month + 1, 1) + else: + start_date = datetime(year, month, 1) + end_date = datetime(year + 1, 1, 1) + + async with db_pool.get_session() as session: + query = text(""" + SELECT COALESCE(SUM(r.total_amount), 0) as total + FROM reservations r + JOIN properties p ON r.property_id = p.id AND r.tenant_id = p.tenant_id + WHERE r.property_id = :property_id + AND r.tenant_id = :tenant_id + AND (r.check_in_date AT TIME ZONE p.timezone) >= :start_date + AND (r.check_in_date AT TIME ZONE p.timezone) < :end_date + """) + result = await session.execute(query, { + "property_id": property_id, + "tenant_id": tenant_id, + "start_date": start_date, + "end_date": end_date, + }) + row = result.fetchone() + return Decimal(str(row.total)) if row else Decimal('0') +``` + +### The Fix — Part B: Timezone-aware date comparison + +The key change in the SQL: +```sql +-- BEFORE (wrong — naive UTC comparison) +AND check_in_date >= :start_date + +-- AFTER (correct — convert to property's local timezone first) +AND (check_in_date AT TIME ZONE p.timezone) >= :start_date +``` + +`AT TIME ZONE p.timezone` converts the UTC timestamp to the property's local time before comparing, so a midnight-Paris reservation is counted in March, not February. + +--- + +## 6. Bonus — Hardcoded Property List Leaks Tenant Structure + +### Issue + +**File:** `frontend/src/components/Dashboard.tsx`, **Lines 4–10** + +```typescript +// ALL 5 properties hardcoded for ALL users — regardless of tenant +const PROPERTIES = [ + { id: 'prop-001', name: 'Beach House Alpha' }, // tenant-a + { id: 'prop-002', name: 'City Apartment Downtown' }, // tenant-a + { id: 'prop-003', name: 'Country Villa Estate' }, // tenant-a + { id: 'prop-004', name: 'Lakeside Cottage' }, // tenant-b ← shown to tenant-a! + { id: 'prop-005', name: 'Urban Loft Modern' }, // tenant-b ← shown to tenant-a! +]; +``` + +**Impact:** Client A (Sunset) can see and select Client B's property names in the dropdown. While the backend correctly scopes the revenue query by `tenant_id`, this still leaks structural information (property names, IDs) across tenants, and allows any client to query any property ID. + +### The Fix + +Fetch the property list from the backend (which is already tenant-scoped) instead of hardcoding it: + +```typescript +// FIXED Dashboard.tsx — fetch properties from API +const [properties, setProperties] = useState([]); + +useEffect(() => { + SecureAPI.getProperties().then(res => setProperties(res.data || [])); +}, []); +``` + +The backend's `/api/v1/properties` endpoint filters by the authenticated user's `tenant_id`, so each client only sees their own properties. + +--- + +## 7. Fix Summary Table + +| # | Severity | File | Line | Bug | Fix | +|---|----------|------|------|-----|-----| +| 1 | **Critical** | `backend/app/services/cache.py` | 13 | Cache key missing `tenant_id` — cross-tenant data leak | `f"revenue:{tenant_id}:{property_id}"` | +| 2 | **High** | `backend/app/api/v1/dashboard.py` | 18 | `float()` conversion of `Decimal` loses sub-cent precision | Round with `Decimal.quantize(ROUND_HALF_UP)` before casting | +| 3 | **High** | `backend/app/services/reservations.py` | 32 | Monthly revenue always returns `0` (placeholder), timezone-naive dates | Implement DB query; use `AT TIME ZONE` in SQL | +| 4 | **Medium** | `frontend/src/components/Dashboard.tsx` | 4–10 | All properties hardcoded for all tenants | Fetch from tenant-scoped API endpoint | + +--- + +## 8. Loom Video Script + +**Target length: 6–8 minutes. Keep it concise — one bug per chapter.** + +--- + +### Intro (30 seconds) + +> "Hi, I'm [Name]. I investigated the Flex property revenue dashboard and found three bugs — one critical privacy issue, one financial precision bug, and one unimplemented feature with a timezone flaw. I'll show you each bug, where it lives in the code, and the fix." + +--- + +### Chapter 1 — Bug #1: Privacy Leak (2 minutes) + +**Screen: browser with two tabs** + +1. Open two incognito windows side by side +2. Log in as `sunset@propertyflow.com` in one, `ocean@propertyflow.com` in the other +3. Select `prop-001` in both dashboards +4. Refresh repeatedly — show one client seeing the other's revenue + +**Screen: VS Code — `cache.py` line 13** + +> "Here's the cause. The `get_revenue_summary` function takes a `tenant_id` parameter — you can see it right here in the signature — but line 13 builds the Redis key using only the property ID. `tenant_id` is completely ignored. Both tenants share `prop-001` in the database — that's intentional, the schema uses a composite primary key. So one tenant's revenue overwrites the other in the cache." + +**Screen: show the one-line fix** + +> "The fix is one word — add `tenant_id` to the key string. Now `tenant-a` and `tenant-b` have completely separate cache entries. They can never interfere." + +--- + +### Chapter 2 — Bug #2: Float Precision (1.5 minutes) + +**Screen: browser — dashboard with `showRaw` mode or API response in network tab** + +> "The seed data has three reservations for `prop-001` — each is $333.333, designed to sum to exactly $1,000.00. Watch the raw API response." + +**Screen: VS Code — `dashboard.py` line 18** + +> "The database computes the sum in NUMERIC arithmetic — exact. The Python service reads it as a Decimal — still exact. But then this single line — `float(revenue_data['total'])` — converts it to a binary float. IEEE 754 floats can't represent most decimal fractions exactly. $333.333 in float is actually 333.3329999... The frontend then does `Math.round * 100 / 100` which can shift the result by a cent. Interestingly, the frontend component has a 'Precision Mismatch Detected' warning built in — a deliberate hint." + +**Screen: show the fix** + +> "The fix is to round at the Decimal level before we ever touch float. `Decimal.quantize('0.01', ROUND_HALF_UP)` — this is standard financial rounding, the kind banks use. Only after rounding do we convert to float, so the value going into JSON is already a clean two-decimal number." + +--- + +### Chapter 3 — Bug #3: Monthly Revenue Returns Zero (2 minutes) + +**Screen: VS Code — `reservations.py` lines 19–32** + +> "This one is interesting — the developer wrote the SQL query, wrote the date range logic, even wrote the commented-out return statement. Then left a placeholder: `return Decimal('0')`. So `calculate_monthly_revenue` has always returned zero for every property, every month, no exceptions." + +> "There's a second problem even if we uncomment it. Line 10 creates `datetime(year, month, 1)` — a timezone-naive datetime. PostgreSQL will treat it as UTC. But Sunset Properties' buildings are in Paris — UTC+1 in winter. So a reservation that checks in at 11:30pm on February 29th UTC is actually 12:30am March 1st in Paris. The client's internal system counts it as a March booking. The API, with a naive UTC boundary, misses it. Their March total is wrong by $1,250." + +**Screen: show the fixed SQL** + +> "The fix joins the properties table to get the timezone, then applies `AT TIME ZONE p.timezone` to the check-in date before comparing. Now the March boundary is March 1st midnight Paris time, not UTC midnight. The reservation is correctly counted." + +--- + +### Closing (30 seconds) + +> "To summarise: one-line cache key fix for the privacy bug, one-line Decimal rounding fix for precision, and implementing the stubbed monthly revenue query with proper timezone handling. All three reported issues — Client B's data contamination, Client A's March mismatch, and the finance team's rounding concerns — are now resolved. I've pushed the fixes to my fork." + +--- + +## 9. CTO Interview Talking Points + +These are the deeper technical conversations the CTO will likely want to have. + +--- + +### On finding the bugs + +**What they might ask:** *"How did you approach the investigation?"* + +**Key points:** +- Started with the symptom descriptions and mapped them to system layers (auth → cache → DB → frontend) +- The "sometimes" qualifier on Client B's complaint was the key signal — deterministic bugs don't say "sometimes." That immediately points to shared mutable state: the cache +- Read the seed data carefully — the shared `prop-001` across tenants is intentional, it's the test case +- The `NUMERIC(10,3)` column type and the `float()` cast in the same path is a classic "impedance mismatch" pattern + +--- + +### On Bug #1 — the cache design + +**What they might ask:** *"How would you prevent this class of bug in future?"* + +**Strong answer:** +- The root cause is that the function signature *looks* correct (accepts `tenant_id`) but silently ignores it. A code review would likely miss this. +- **Structural solution:** Wrap the Redis client in a `TenantScopedCache` class that automatically prepends `tenant_id` to all keys. Tenants can't "forget" to scope — it's enforced by the type. +- **Testing solution:** Write an integration test that queries the same property as two different tenants and asserts the responses are independent. This test would have caught this bug at write-time. +- **TTL consideration:** 5-minute TTL means the bug would manifest and disappear cyclically. Monitoring for "same property, different tenants, same response hash" would catch this in production. + +--- + +### On Bug #2 — financial precision + +**What they might ask:** *"When should you use Decimal vs float in financial systems?"* + +**Strong answer:** +- **Never use float for money** — this is a hard rule in financial engineering. Float is a tool for scientific computing where approximate answers are fine. Money requires exact decimal arithmetic. +- The right approach: store as `NUMERIC` in the DB (already done here), use Python `Decimal` throughout the service layer, only convert to float at the API boundary, and only after rounding to the display precision. +- Better still: return monetary values as strings (`"2250.00"`) from the API, not numbers. This prevents any language's float parsing from touching the value. The frontend parses the string for display only. +- Libraries like `Money` (Python) or `dinero.js` (JS) enforce correct handling and prevent accidental float arithmetic. + +--- + +### On Bug #3 — the placeholder + +**What they might ask:** *"How do you handle unfinished code in a codebase?"* + +**Strong answer:** +- Placeholder code that compiles and runs but returns wrong results is more dangerous than a crash. A crash is immediately visible; silent wrong answers erode trust slowly. +- Better patterns: `raise NotImplementedError("monthly revenue: see ticket PROP-142")` — this fails loudly and documents the gap. Or feature-flag the endpoint as disabled until the implementation is complete. +- The timezone bug hiding inside the unfinished code is a good example of why "leave it for later" compounds — the timezone requirement is architectural and easy to miss when added as an afterthought. + +--- + +### On the timezone design + +**What they might ask:** *"How would you design timezone handling in a multi-tenant, multi-property system?"* + +**Strong answer:** +- Store all timestamps in UTC in the database (already done — `TIMESTAMP WITH TIME ZONE`) +- Store the property's `timezone` identifier as an IANA timezone string (already done — `Europe/Paris`) +- Do timezone conversion **in the SQL query** using `AT TIME ZONE`, not in application code. The database's timezone library is well-tested and handles DST transitions correctly. +- Expose timezone-aware ISO 8601 strings to the frontend (`2024-03-01T00:30:00+01:00`), let the browser format for local display +- For reporting (monthly/annual summaries), always parameterise by timezone — the "March report" for a Paris property and a New York property have different UTC boundaries + +--- + +### On the overall system design + +**What they might ask:** *"What else would you look at in this codebase?"* + +**Honest but constructive answer:** +- The `tenant_resolver.py` has hardcoded email-to-tenant mappings — this pattern doesn't scale. Tenant resolution should always come from the verified JWT claims, not a lookup table in code. +- The frontend's `RevenueSummary.tsx` hardcodes `activeTenant = 'candidate'` when no override is passed. This sends a debug `X-Simulated-Tenant` header on every request. The backend ignores it, but it's dead code that signals an incomplete tenant simulation feature. It should be removed. +- The `Dashboard.tsx` hardcodes all 5 properties for all tenants — a client sees other tenants' property names in the dropdown. Revenue is still scoped correctly by the backend, but it's an information leak. +- Positive: the `SecureAPI` client in the frontend has good bones — tenant isolation validation, request deduplication, cache invalidation on token change. The architecture intentions are right; some implementations need catching up. + +--- + +### On how you'd prevent these bugs systematically + +**What they might ask:** *"What process changes would you recommend?"* + +**Strong answer:** +- **Integration tests over unit tests for multi-tenant paths:** A unit test of `calculate_total_revenue` can pass while the cache bug exists. An integration test that logs in as two tenants and cross-checks their data would catch it. +- **Type-safe tenant context:** Use a `TenantContext` object that's propagated explicitly through the call stack, rather than strings passed around. Mypy/type checking can then enforce that tenant-scoped operations always receive a context. +- **Financial amounts as value objects:** A `Money(amount=Decimal, currency=str)` type prevents accidental float conversion — you'd have to explicitly call `.to_float()` and that's a red flag in code review. +- **Code review checklist for caching:** Any new cache write should have `tenant_id` in the key — make it a required item on the PR template for backend changes. +- **Staging environment with cross-tenant smoke tests:** Before any deploy, run a script that logs in as each test tenant, fetches the same property ID from each, and asserts the responses differ. + +--- + +*Guide prepared for Flex technical assignment — September 2025* diff --git a/NOTES.md b/NOTES.md new file mode 100644 index 000000000..dab893641 --- /dev/null +++ b/NOTES.md @@ -0,0 +1,123 @@ +# Investigation Notes +## Flex Property Revenue Dashboard + +--- + +## Bug #4 — Database Pool Uses Non-Existent Config Attributes (Root Blocker) + +**File:** `backend/app/core/database_pool.py`, **Line 18** + +**Discovered:** While trying to reproduce Bug #1 live — both tenants showed identical `$1,000.00 / 3 bookings` which is hardcoded mock data, not real DB values. + +**Error in logs:** +``` +❌ Database pool initialization failed: 'Settings' object has no attribute 'supabase_db_user' +Database error for prop-005 (tenant: tenant-b): Database pool not available +``` + +**Root cause:** +```python +# BUGGY — builds URL from supabase_db_* attributes that don't exist in Settings +database_url = f"postgresql+asyncpg://{settings.supabase_db_user}:{settings.supabase_db_password}@{settings.supabase_db_host}:{settings.supabase_db_port}/{settings.supabase_db_name}" +``` + +The `Settings` class (config.py) has `database_url: str = "postgresql://postgres:postgres@db:5432/propertyflow"` — a single connection string. The pool was written expecting Supabase-style split fields (`host`, `port`, `user`, `password`) that were never defined. + +**Impact:** +- Every call to `calculate_total_revenue()` fails silently +- Falls back to hardcoded mock data in `reservations.py` (same values for all tenants) +- **Masks Bug #1** — mock data is identical across tenants so the cache leak is invisible +- **Masks Bug #2** — mock amounts are clean integers, no floating point edge cases +- **The system appears to work but is never touching the real database** + +**First fix attempt — `database_pool.py`:** +```python +# FIXED URL building +database_url = settings.database_url.replace("postgresql://", "postgresql+asyncpg://", 1) +``` +This fixed the attribute error but exposed a second issue: `greenlet` library is missing from `requirements.txt`. SQLAlchemy async requires `sqlalchemy[asyncio]` (which pulls in greenlet), but only bare `sqlalchemy>=2.0.0` is listed. Fixing `requirements.txt` would require a full Docker rebuild. + +**Final fix — bypassed SQLAlchemy entirely, used `asyncpg` directly in `reservations.py`:** +`asyncpg` is already installed in the container. Rewrote `calculate_total_revenue` to open a direct asyncpg connection using `settings.database_url` — no SQLAlchemy, no greenlet, no rebuild needed. + +**Result confirmed via curl:** +``` +tenant-a prop-001 → $2,250.00 / 4 reservations (real DB data ✅) +tenant-b prop-001 → $2,250.00 / 4 reservations (WRONG — cache leak bug visible ✅) +``` +Ocean Rentals has zero reservations for prop-001. The fact that they see $2,250 is Bug #1 in action. + +--- + +## Bug #1 — Cross-Tenant Cache Leak (Privacy) + +**File:** `backend/app/services/cache.py`, **Line 13** + +**Visible after:** Fixing Bug #4 so real DB data flows. + +```python +# BUGGY +cache_key = f"revenue:{property_id}" + +# FIXED +cache_key = f"revenue:{tenant_id}:{property_id}" +``` + +Both tenants share `prop-001` (valid — composite PK in schema). Without `tenant_id` in the key, whichever tenant requests first wins and the other gets their data from cache. + +- tenant-a `prop-001` real revenue: **$2,250.000** (4 reservations) +- tenant-b `prop-001` real revenue: **$0.00** (no reservations) + +--- + +## Bug #2 — Float Precision on Revenue Totals + +**File:** `backend/app/api/v1/dashboard.py`, **Line 18** + +```python +# BUGGY +total_revenue_float = float(revenue_data['total']) + +# FIXED +from decimal import Decimal, ROUND_HALF_UP +total_revenue_float = float( + Decimal(str(revenue_data['total'])).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP) +) +``` + +DB stores `NUMERIC(10,3)`. Seed data has intentional 3-decimal amounts (`333.333`) that expose IEEE 754 float imprecision. The frontend also has a hidden `Precision Mismatch Detected` warning in `RevenueSummary.tsx` as a hint. + +--- + +## Bug #3 — Monthly Revenue Always Returns Zero + +**File:** `backend/app/services/reservations.py`, **Line 32** + +```python +return Decimal('0') # Placeholder — DB query is written but commented out, never runs +``` + +Also contains a timezone bug: `datetime(year, month, 1)` is timezone-naive. Properties in `Europe/Paris` have reservations that cross midnight UTC/local boundaries — e.g., `res-tz-1` checks in at `2024-02-29 23:30 UTC` = `2024-03-01 00:30 Paris`, so it belongs in March by the client's reckoning but falls in February in a UTC query. + +--- + +## Order of Fixes + +1. **Bug #4** — `database_pool.py` — fix DB connection so real data flows ✅ APPLIED +2. **Bug #1** — `cache.py` — add `tenant_id` to cache key +3. **Bug #2** — `dashboard.py` — fix float precision +4. **Bug #3** — `reservations.py` — implement monthly revenue with timezone-aware dates +5. *(Bonus)* — `Dashboard.tsx` — fetch properties from API instead of hardcoding all 5 + +--- + +## Key Files + +| File | Role | +|------|------| +| `backend/app/core/database_pool.py` | SQLAlchemy async pool — was using wrong config attributes | +| `backend/app/services/cache.py` | Redis cache for revenue — missing tenant_id in key | +| `backend/app/services/reservations.py` | Revenue calculation — monthly function is a placeholder | +| `backend/app/api/v1/dashboard.py` | Dashboard endpoint — float conversion loses precision | +| `frontend/src/components/Dashboard.tsx` | Hardcodes all 5 properties for all tenants | +| `database/seed.sql` | Both tenants share prop-001 (intentional to expose cache bug) | diff --git a/backend/app/__pycache__/config.cpython-311.pyc b/backend/app/__pycache__/config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..446dbbfe864158cf20eb68069e8f4559e1db389b GIT binary patch literal 12367 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 J0sZip{sM~Kt literal 0 HcmV?d00001 diff --git a/backend/app/__pycache__/database.cpython-311.pyc b/backend/app/__pycache__/database.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b609bd900a7f5a8a0bdcee5da6240d69144a4ef2 GIT binary patch literal 22454 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 D&D`57 literal 0 HcmV?d00001 diff --git a/backend/app/__pycache__/main.cpython-311.pyc b/backend/app/__pycache__/main.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f094528a6d9d2fedc2353ba4dc2c79247a0449b GIT binary patch literal 22652 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 G(*Fy$>Ita; literal 0 HcmV?d00001 diff --git a/backend/app/api/v1/__pycache__/auth_info.cpython-311.pyc b/backend/app/api/v1/__pycache__/auth_info.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e9b73b391416b3ea8659df0f85c4bf1f8569f4a7 GIT binary patch literal 10140 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 K(wc0t+5ZFk@24aH literal 0 HcmV?d00001 diff --git a/backend/app/api/v1/__pycache__/bootstrap.cpython-311.pyc b/backend/app/api/v1/__pycache__/bootstrap.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..97c3312c5243f3889b140b28ae2c6279ba99c447 GIT binary patch literal 27620 zcmd6QX>c3YnP4~0#zg|WNl+wsilBJtJ}A)=Pl*yG(Ih2Xlw}BHLlk5Xpt?aFFlcKN z&xBT~W@wM5%t@pQlXVh0@l;q_Gqc*NnOcpL%qmlvOt-eZ#$uzgwsyTU{xb!y<64)0 zZ0+~GZUEf?Xfw&|>^2`>zpLNEh~F4;Pq}qeK=*y9`j67>pr&de%zkA{Iv`N@eH!B7CqGm5 z5MRyOS;xCY-`7D5{FE3Ei795Cc`*&FYpRhgnQEG)*wXLPQ_VW+D8-h&MzQ6A%I`yu z{RnTMucsDS64|YI0MR zYhXQ)wnNGHtI{?=+Ri}jYFDOvR1UT=(DH7Rc4S~&^Z}Q49NFeeI<_TH&b9`+p

F zGv>^L?NGuFRmK@7+osK_VD4Te_jc%O1G_CR_njNozvHWOzeHorp@h!7e0Q@`K9zGbJg#a#abs@kUt;eem( zOxFk!%tyj}z!MG51^6!O$2bIDebUl5HZmSrfaWF5gMoQy4WD!zo17dQx-k=&$C`T$ zN#-Z!y+apM+cx~fh03JeulU{{zoX` z<3m`AE@__g-{6C>KvEx#hCXH?FxUY==Hs2<`WWG?S05|qgX|Hg%cW4@MksgxA1tO~Ff-{%>flz+b3}l#j42tX1b|~;IDnL!q0Izjt06I_U1BQSxU{bH- zfSJ`{r3=RBNeq)8mtEcPy@8~%kW@x>-kMZKC6!SVYRZ&t38-S!xj+eKRSBBfYw}_; zd1=zX_m&M~tQf=EU{%?ZuKx5I8dv6KZ0|q>XLU57T3=)ZeEHf+8Wv#EBu(;KN;+X& z=l$WEK0XkQ!Z`CuTXuEvFj>gbf>3_W&qaOLf`RMkS(xSnGdSV-Br_L?`mx}o6&F;% z7YtvDobp^8vTr=exS#4=FKbpO1~q_6Q1)KV!wj1Dv@(Xrf+tHnYGF|gGIX5Ops~vv)ufV#c`b!v& z2!GI5S)tysepJRnNnqV5}D+8JV9M+4yi2hfPX%7Evk zz)b=zv5;+Y0Unq@)4?zqsF*b~2t8lWJuyo-(kZ9nwm~so9fvz7*9{hrmGOAEPIx69 zvw^5jo;*+jw+q7dVj9GSZc$HdhgQsj?GTt%uh7`D_Ok2|42MX=XEG=fB*$z?yX@dd zx9h$RTBD1#ZO|IIippk%GdX6KgL>p@({hcm7^T8xSYbJhs@{7bK@a?RCsrV>r=#gucweLDjd2}IzeGlH z(GWLqCRPW3`g^)rdV;c0QEa#JT*-_zYtU}%tEyD#)Bt9TIjPij%Oqn>aY~EetQs?s zDu))KSv1CtS8)B3XP%y=7ERGK+74l>*!H}KHIo_1L`$<#ag(-|Fk>zEb81dgaTC|F ziTtf`6KiAbzo$Y-VczSsB|vWaWt#JD(6

J9p~C?{3nzAcXHbNaS$Iw$MONw=9X zFvra~W57hqvpvg}yaxR?NNGn-Tkl1S=8Muzd|}mm0c6KlmSNL;QND>U>~RZkid%U@ z+{WwTc5Wih3{n@G79DZZsx8~Xtc$IPJJ`zX_Kc&>R^d9*wwI>vG;d-aRcmG_qs;?m zXbsNe`#GzSrZ$nYTa$DC+^;R1bKEpRHBr&3Y>S&Iu4A!CQ=%gqn{}~UDECfkixc> z1lbM`qB>*;Nm_!u4=a5wFsa$JaG~R-_vt8D3h<{c)GyL;z>l*NbroXsAC}fmxwF(; zG)!F&i<_RFI|yH>u{Yl-AQ-Gbd2vzxdN6wV9bHn_wLMACt9RrtEQe-c=f5$}Jrmnn zsAIbhg(5Tl5dTb9CgEi$h{rAPAK~v7C2VEUOiZrPYuGBAqe}j!dW2=5|VYM~v8@vsAF0)yq4j(j8k^#Au9icQ|Jj_-F)11+ZT3 zT5u-7A*v0#a=_1?B6~hJ1Oe(E;f_JTru*UwevNr5eNoQ|VEogo^s4u5yRg0gv8P|~ zyzubqqpF|2ES!De@zEDBf!6$sc8Ogzg?Z8)+zF`vKTB`CguQ|DQ0Wct4FSyT<+X;j zk#{>DbUkiACbUmKdiK$cUz`_Sn0|b68soL*U$irvs?P95BazTQbBBbmL!QfYNQ$Dm z`gF1_MCRB0>y~#z!ZTx!yT*jBE5ezx!gD_9%te8{^7zaZb>fZOq_emIC?Kf|vSc7* zraqPpu%0g(HUPsJyx#K#GaQHlA;)@RwVo)@U?DB=1J(_Jp|R#6jswpnOpWke1*NmO zd5e$p&M``tiV5 z!L5L+$H)>DRhy1zz=-n8e%_aj1gMQXsH6jfXAp=JZzXzFb0rhu&WRwCDE*ZIcfcea z;ESOokM@!2Awpi{?qysMl0O4K{tH0v<)xG|QO@%FcA>agDBibbSU3N$_|~zf=He7Z z8+RmX>(_P(&Tcft+XZHO%Cy^9@|lTpl>f?6B9yj#qNg2Oe@%h)5028?XN9sB(a|b7 zT0e9Y-yUDKtn3pVO_HPOLr2-|=UzW|=UmE0S;|vRsHP%?_bv z-}?B{iO(3SrA^tDo}U4SxRsT_Zf2!sRf6MDGm=?A9An>kYx)^rXF0y-tPbtFreKvg&_LY;bSu(}5do!M+uTwIxNF95eKq zLw*Yf#uUe7M0O-8OGMGDOAHn$JTV$S-nCArMxkPb|z|?&H#8#G~bjFgb^#taO{kB~wKmOn- zSYRGrmER(BLSjw`%!x#?Ysr%R`y8H>5i)@{Uk7X8TgQyY8mLDN){#p6qiqc%CHkM+ zX>k9%#0a(qxk9GV*Wvf+cEHtSJR+*%7yv~JzO0x9@r!7NdPcgNYmcfZu?=WE!avEU z9@RO;=`1QYK?SKr9nkDpJLS2Oq2t&bN@O)dJ*U&+o7HP;zKT4wyoWX9(d-53Z7t=u zs;XBuOKqA(eO!Nq2<9-wJRPKfKS5Zj;R8T_AY(~+2>oHu^dhon@*dzX7z)wg*_?s? zFfSTjF@zcUouxlE?8_XA?04!*%m1~$L>@_|FFBjq2fa$z$6+JzMAGixwuh~SdpMi( zZ_&fHoOxJyw%T)26`rm6JzO}QgUu0wZfeGw*ka@;WP2L9QMp_X=wm11?wa{pm|k{8 zGvZnbXTLMM!nLghK0pbftxL73V7BMb^)&Tcub#5PV>?S~hArB7Y~wmDq{7s3Bp}OU z^+?sryiQrdhE$_xbZ1(87OPU+0ng>2OkyjklL{M^=a4JPjiEIKR;)G$aa7VHrUx`N zhX9@+Z?T4)go?1jlNMI=c#^gVH>*e&_@qe|GXP!*l7j^hUjPpr@Jv>-As{eErsAhq z&RZ084|TzsOIE(2yMvM!nw!JQDBSB|a3|?GHC_0H^-u^zdswk&VogXYD{NszVpUXf zCefcm9(*lWKq5Cx$Y#A^wPE$x+uJe$G6L^`RNOdNu`)%($rHR<=`IeD!B|yJ7byap z9uMHdNR20%&`z00&7DK9kqt~Q%n~e|n}h)F3|eO~%0B16IUVrH!cz|E6YhDmUPQ}> z7LFcw9xSg};b>&I_DP$n;Yo+$QIKuq4J3haBa4_6OgmYm)K&5GxY8ALSjK~kbNZ8e z8B#35kN>Y36d2LMmeq5jvs-d@-x^7noqv2xFxP^~pcx0(EkgN0Fd}nEVh#z+p(n+a zD;BA^QD7RMmXzH(kuuqh4IkOd054uXfM{_YqQ!LtEnXgY{rsKtGEQt*4vG$so4AUF^e2KC`$z($Mqdj-FBgF?|T1|ZFyK^+ydiH<3J6F1IbpVa{Jc%gz|l0 zL}tIl>=&5*i8@dAQ}{Y#(pXRfVnfyvW4B!6d`wY%N^nDnNwoZpl^; zXryIVqN`Wx>R$q^yj`?!6YSdn6YbuW_J1z7LvQQ`>`}2Y?Kt$nC6pfmBQm`b(kcOBc3v7tpVQf~qz8AZ`5xc%o?)qb*V~gb2B6q&3B}ktzD_+sj zEIFDrLr@7r&^SrMN_tQv?LQ&xfA$dv9$Fh53yjF@mYCfFvpdny zq!cYMb!w9y(PlEDl)Lr!jxC)N4V6G8f#i@!4$NOOecSqXQ}6Az4z%mvd!})qMgNl) zBe;Lk)wg%3h5A{Gb=a-{S$E@bh5m0UjNty8`u<%brPR+$t;a3;pKobAZqWa&!3b^* z6vPdUpvA4Q>}0eUP$(5*d?n+~mJtUeEgQX$vbw?t8M)M;V z0W3T}auLA7D3t@+s2Qsb2(BWwI49j^=8*}IzYLkh{rM((NZbFauk%L2c|V6BLs4Y5 zH0WoSx}RarE-aciQG=4Wd4qXfnpcOi4b$d`Dghxa-!N@OUcQwZrp=#`Rrf90?_s82 z19F#9_XhXA+6R5{cZ-&|WrKF+)ExxM8>Ot6%@I&9T0u0pZNv0AwdX1}n{t+3v}(pq zCD6{UX|_6UBqBg7*zOJU&Kt*kq9AUCKI$Q2|GjYoTPq7UI32qM!{W>}nll0>%fyMs zQ{0HIEZ~4xw>D(cFzVo)UuxQE%eF4-V(SQTQy*sv2@c~75lAAstvtXGIJ0QeXg zX19VSAz=asfxb|&)OpV=7g?AG=K1tZAXA8h(u2BttS1uofJ$9ZBOT>>p^`)>MVQw~ zig4{?rs2o}=rwZBLTs#I0#&bMx#`FtkN_xsRPox8WWu55j$rE6w8*g|U3|vDcX%=a zNSPYzgD)my-J1G?0wvNeSmz8EA6ly_kUNY86?r__iUA>JKso0ZCQsYQAj(#=r9vE& z))tG|GT}X*FKBP9W{iseS1PpZlUfdm4ZTuBuTT}1jcAWZ_K0AQBr4h@5Z+9$ zU0s`&Dt18q9OEE;M0;8H#94u|fD}b-c~-YJ{^PShJi9*p&WrE9D2K@Q!=3+O?|XY6 zHUIUYpB_?&3m1GJT$p)$VMbuX;)RHG0Ynv;k8BI^SN<1}@AQD~f66Zi9@L%Gf$(FI zK84Z`e5t>X-4O2@$7rx2Bx{?f{XIZUr6)~=Wt2|TZI|lyq^NSoC@tH|)m!Kv?_T0bB*_e#yZ zBq-r&|3T4ri`H(6o&%ESfKcDFeC#9WC;OXrVaxRgTfqYJ=(7A4e8CTVbB}#tctP} z%S7+lm7}ttMtEj2Ph!&|FfC~+A0#$<6x)E6p>6Z2{7lsDKOI=7-x+>)SSa5O=0SAH zE;54>Gbk{Fg~T~P{}XXeD}a;N28%~`P(Lj@Rtv9R?6974>VI*t&w9$H|D}-z&o6C8 zur>56V)2B2jRBqd{~!IDr*@g4I-uT}Czr|vn%0z#B#M$cpyMi7RQxolusMpevu0pq z>vCDwKqCXw7KAS&k6PyU%DxAm~ zYe$?&B?b4WG@xXD927f8q|OltUmncF z6LxQ`Er*k{*#!GCZ{v0|d65pqEEi2iIJ01LWEUCP6xObrL#IEIlrj9$x|oQ@UhJbL9%jng<>N zS8f2zmjWfVjQO>GUB8)n&us1Q(ZA=a>))e)ubW2q9wXSA*@>KM0*u;V;%0ym1g4)X zGi?LrS&kCl2278f#kq42dXOCG zf{JQpDbAM73%ppjLe)crVyC<|0w7VHSk~{H#KvSKT`Cay`xrsU zuq>Q3%4C?VdJLry_zyZ`$)aqL(7}ANBy409xwMq(1MWMJs2TgF0jxAA ztx-rR$zJ<`z45WVQE1vD+V@KKy&s~E*7E7J%wq!;EemC-PT47^M=A!fM4Iw=D);-L zQR&dL(BoqDxKuq3=l%EFk2t;4_7MU@L855YXLU>{tB;%g?TAydYP5pIC8QML>^Aopq z&;=rqhC#djrzRTQKeZddj#;xO!hnb`f=!Q{=|ov^AT*q`&n$2pEH*NQlMXmEH-l#` zFG0G?nv+t9N)gze1lCu+{?HYOmY?s#>qlu1iYurrBt+o^|MwtZQ9`gGzv0ZU=H zo(ug|d8Kngtsp2j1KTzO8(9OK{?W4B3+h~G+gDg9qD_OW$txLTldDntHh`x&ZCuoc zcjxI6ZCx~~PdBU<79^OE^_q{)5*-NRD@LM01n(?7*64Dm`Y`ug&LSN9Uo^*Q{++lf zs$yz_rr4^cUaI{>H9nx>a>bSQ7pfs^1hIfB-?$3(Ut~b+WR13@zXvT903PXQqq!K@ z#bEbhZ84ZJTGsq;oD;LbxWTmq+Bt+JYRh7a?g68kEhf4(Thn!hdhG`NF6M3e58xEr zCi>5*?LXF~p6^7@2FMt;6hh0=Wq`jdUnl`0MHD%dr&Fol(ax+-oxi$lI4N1KE(MtJ z6=51Qsr286_4}jD8rJp#o+#s*HY^v(BISX6U~IFRiCQ1%33=Gc*C-HhY|sWB6}M{F zV{Q%`eHq=6t^;TRsaAsad#&#)+OY)V?P`rk?ONd(ZOSl;yB#?> z)oeN^Rmw1EWx~lXZJpek&PkP$IeH zwmyn-m-Hy*h!+7`cnX{4bIxOyD+wK|TMH}oi z-e8W1cf*wJc_|$mrrnk+IF1*`opF7%FWVJY8q#hp^jU38hpXS(G;9akc~2iVvt7UO zj=SOB&4Lc>J;P@9f42Lcb+I&Fs>LeEKK##yNi3Gd%c8^C9(alDf85qh%&qP5GFWpv z)L(;tXa0-|Z)R=Cx$P>Tj8V$kd#PwH=20qR9^O6v1F+p%k!%~v++d@+TO)IKO(!rr z3*AnGQd2^RrmvAHbg>O)Ps$h$fQBj%8$HC=={X4mX0S8lzX^g&RH{UQXxr!xl)H8! zx!Zv%x9E{Msb1x?F+T@)$`udS{cyKVcvguWMzRP#CuET)LT3JRm&7Sl#92FDC}S$qJf(^9IJqK${D6LhzWt8)Q#@okYSOukXY8|j}p!>+_EEw z_#l1KMk0OWuAw9z-IM7&ykEyR$0uEKw0{;fTLUu@xU+|AhCE}<=lf5eo}8E*?;E?| zAt&CjVwpk28uWO$S23xzL#ePV*iN4)gXn(+(cB_h2f&(vU*-X7kwVVNr>$VgbYl>& zA%iQ*@YV*Px^%>Cyk~*SxlH$fx$ZTeiZPSGEgyz^cVgzIo%?qW?H&Nf@bK_~p#!pG zaCooR0_3Z5ZwpG@LB}^T8}Ti0p`?k0(S*~~_RDaV6?ii(W;r(EbvZ53vTaF^aOwx=7-I4a;2_pP7Xr>$t$KEjW$wF@6~JZ9ZN4%X?rB=kQ#$7)4p!xwzlr@M&X;fusg%W>2A`8=I@t@yQm#U~4^wy7uGc(w!8dP1;K zfEE+L%-!n5ry^=$VJ8;|!TmyP{&%tVoUc&hMZWb7R{`or;Z0X$r{It*gVX(EICj|s zz!%Yb4=pYDiWzrwZSUF+gH5E6uU5NQ{O=#hk!mWW7tLjf*)s?gD#!6r(#$_L1d1VjwBz1E<3GehEqaSpy#iWDXHWN{bq zvkPbi(ZZ7!MB9f*{0Of)Y4-Cs!!yB1(lqM_O*RfCwlb~*icaU@gQOX-hcIlT975To zX(2ijj$FrUFCs8hfMp~rC;P^a4o&*ThbG2OpPCr*O^%!#@|~RUmUI6aOMDx@lW(W+ zWt)BjqmZ%AT|?^~OeF96tPeMAJWkHP#B+avvHuQZLH`P6oIE+^&0WXv?115nNS3Hp zJ@3Q01p*WZlaU9^mHQE-fCI9vWBZ+Z?57~tNA)cv^b|G<=n{h!rQB^7t8-*De` z-#QMuAFeHuvlR}i;IY_ZV^7N9u=IT7tb&ux%dg#;ff1R0iRl-Z{zO^T zlI029xpq^k@GjZl1b9td!d?Hw)AYT`x6gg&{M+Z(d&HLBhh<{(kmwnfJi|{Knln)c z|Lx&_bNJywVeDCP*SNH6Tx=Pa&wivV#ujUe0t=2}jEYRdXCSd?5Q^b!eD~@>`7JQr zaGc0!`^Jf{od9U(dO^1ym-dawPT3Zoy&ye%Q4!s2*f!VoaUNWz-3C8t_ z#aLqcH3ilul+kDgm(dKZ1ItMf>_{*UJZAmJJ~$m!-Yu1Pi_CV3!HWRMT>!-v zK$tR?hq5S#vfG66HnF^2DsLB=Z4$FhVDJ=BrfRF9whL}QVr zOp))GZ(pw#%MVJbBUf#1BnDDF2d5k{%J_U@_GA)&1Q0cbJxqbbTY zw~j)(mhQFd>sQ~6{S|0*4N1*ILdnVHtt$<8+n3uP?Ywp3Npsi#)A-DM6Py>;;!<}X zyutiz;*nb%IwK98k^Nwch8HEni-O_Bgc%WEBS&ZS7Dv`!ez@yl|HECI5BiTZ6){cfQQ)H9clK4?u;HA_{U33qGCW^%zwMXQJ^t$VBc&F{Lxt!rkyC5GK*k2=Jp4;YX$QGdopLbNAdE=kK0R z?W!p^r6{m&olNym?l$H87L00@`~Kj)kv}?);@>Q@mt@c;<_fYTkSO>Q0e`44&(5nAQs}bBWcUD^3 z9SmQCt9W4x40ICOnIJ()BR>3l z5e$M;IPYNvL8q!8;>KR;j%^byH@d2;an8&idLrmAe1w+ z%)1utxO|OP*Jc%o)x1aBF1Y4S)kB;7;;Tp2svQ})RUI$?vfl&UN3X+=>S=@}HIkXf zDmEUO(Oo2-Sbf~A!h=H;kIeBN&j4Oz3pdv(>i`G>Ifi_ZMg==PjYxbn_IOkUMZ%$* z9!0evt=U70%>7hmlxaW4+pbAsnas!B;pBy!GWUB(yWz)ewF$tqW|3U#*Gp_(Mu7A^n-jpw=l1hw@#WP)uMxMd3MZ_srPtqkQw&gOGGge47d z=PfVOUkJ#O#+eXYM($-~iU@NgWKYs5Hz0fAY_bTyguA6cZ)GlWEs)gX?YS561Egzt zTu91fJt9*p&fIS2{s*M_1p0!X0_$@{3#m3uq&zj-mrY-L_13E&l{Kt(yxk3I@nyYI zS?`hs$d~(!e7WrtXVprz;B3mE^~38O(#}DlY#5Bl9F>@(0x?f5MaylEEj5CrX5}VW zAGy2NEuy)n38b4m(=SDLOOu-+TTC7ruMpJHEGl5F}Qg zl&VjH5>qJ>I2LlwqHbvbYg4-HSaxJK%fst{5y5tOSY(b!%n^YYtV_%7x~00O1hrmb zo)%YPHqX*eO6u1Jg#D+5k}|-A>PTZqKrb=R}psr8y{K|>)4w31Um`;J| zd|K&V4G6XlG=>g&Vpga&S+dSMah~y-WtUMUy$b`9zoVkcGeBxwQObktxOa1|js-}q z+7s1KTMIeWF;{TGlSdPp$>(>;F$Szq)`03Ktnph0)&!^T%pkhTe}BU6hAq2$S9tYeKb6GJqZ&K)C-SI3t7Xxd{9tg9wK#kpBW-alb2kNqEhA# zp+34s$N|9OA{K%jK{zq;H^{r-D$v5OIpjrx@;hO)Tm-k8shK2qZICwk$fV@{2~sp7 z1pXN~6u@AmoVB1>2zSicN@2AaPts3{+-rJa_X(kBR4f{mibe%y6gUCpRri@UPToEF zq{<^zwLNh+-8=N8zVUne|77vr;-B7-x(|!>haWbH^+SUDWX1rBjVL)-K%4)rIoPS@ zgCG^K19~o7MiW_t+yiKicQ@AtucY~s9~wI!4q5w2GhR`M$*_l#hATYq4b5=#-{nwn8U$1kF3^Sl(Sbw#H1eMx$e~JEGu1}a z5P3NPVx385{w53m-6A-{A(MG@|U1&x5%H$k%{UQD2+)_9zkpJ>yV)81g%L>UZIf5 z)ZwY6WU2af_Z{~wQ^HcSR4KtOxL>q1OP1zaCcNjcY-#_>;Oews^NKdFWb@u)VEZGX z1FI9-Q1=#rs!X6=l`5i`PPc%6Ab-zHmXWT_pa=MD@^F#wf*Y@ z@4|66a6XtIuUw1K(G9Bu7}~HVzld99F}*Z!Ccs+Llh-;V1K)!ikMw`JNSwkszc3w; z&Rvpy+%@6)%R>BBU`zDthL9b$NDm=n;s!m8FP=UMf$3aTu2<+IG+nt06~*`3nO7$6hspzY7(A|Nb9X{|$)j`>E-*J_qV1#i!-8j(II z(FdQlcCO9}UHxL~fYdsWsHsmGLpr)EMWLN2X-etQ@wBv39WKXyqNj9+Ad8faeDQ)2 z^LKyEEjZdmdYeRV%gGz=jx=`Ba62VfBxiU(wH0LpNet%N0UxJynD!#AR9dh%i*$=b fw`em>=__dfxnPkT(;gCnIkmzUDV-*mfaU)KDO$M* literal 0 HcmV?d00001 diff --git a/backend/app/api/v1/__pycache__/cities.cpython-311.pyc b/backend/app/api/v1/__pycache__/cities.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..26a1954e4dfc19fd89e50aa20ac74f5610e330a5 GIT binary patch literal 5755 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 literal 0 HcmV?d00001 diff --git a/backend/app/api/v1/__pycache__/city_access_fast.cpython-311.pyc b/backend/app/api/v1/__pycache__/city_access_fast.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3825f61e1163b7882c2514de915903c4e8d55e1d GIT binary patch literal 26470 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 WK$JnyGD-=O6o5N223@hT#Qz7_Ehs(! literal 0 HcmV?d00001 diff --git a/backend/app/api/v1/__pycache__/dashboard.cpython-311.pyc b/backend/app/api/v1/__pycache__/dashboard.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96cc0bbe4ead336eff2549124ae74dc9023f28fa GIT binary patch literal 1678 zcmZ`(O>7%Q6rTNG|D{f1NS#z|3>7R_sYS|e#2CwbT&PF8I zQba2V5(h4*J#g?T6s3nEA=DE`ggC9yO0`x(iiD8h<|=UMi8tQbj-xW3d7k&)H*aR% z_h!FMB%%n~!o43q{7FLS53clD*8|Go&me9ijIdBfwonjku^`$~K@zx4EX%f1P;9lJ zc6F(&*?K|m&gF8%juv795)l#hAj*C(HY&tPyqV~$M(McLTj9F>)V$nyI63ssj98fbY^BNglfiIs~N z*WdWqA~ja3R$Z4WDn=-%w#!eXwht z>yab6grfru$G(w)9ASI_1wH&_mj+tw6EB!Lo8_PjpxH%7dmjc8n6> zcGKj=TwvlQBv;zk!CsQ_v)6bd;NvV!3KU)j5m?`VALuQQ9V1t-BB9^w1Fw zi}y+qo6J12e0=C6MmLzl`Irvd<5Tlyt@dP;<~J7xm71$<1<&v*@7Hdx&gnD+;0Jbo z1@RaBcF@0ZGAAb_J;=7wc|V=^#*g=%)dM-_ zJ+1#fd8VzO*wwz4zFKWg_^E6wIpZg1TKcT7&pyE@)Lnrok)x%;wz`dlZX#MKT8g`yt9 zZO~eFG|-Bs!^~QV^0z}}E))=f%C>5pe3e^x7K1U!UXJrxvWSzjOlyOLR3^B?s#22U zUj!QA;3UuHv6mixbR_W5DUOjbd}O)_{tnR$-{%a7$NDRF6}x5fDxC$DKYZsQh>j!( zLL0s0{eN$xQ{K~h8!dXny^UV;hWkNeY&ZSI)R$8`>VcqrKKbdS7oTnk8DGeBR5Y2n zGvQ?xTIoeUz1UI41xO``_Gqdj!T-V7v!PK%YIOJcU1#^jTkm(Y9;}OfBq8xR9!(rF HcQ5`Q%l@n= literal 0 HcmV?d00001 diff --git a/backend/app/api/v1/__pycache__/departments.cpython-311.pyc b/backend/app/api/v1/__pycache__/departments.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f9b1fa4dc8967fe55b89fb6d111b92baec551d70 GIT binary patch literal 22836 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 Z!A{aua_L3Xg4hi#$Dx9yJcpc?{U2a|Ah-Yk literal 0 HcmV?d00001 diff --git a/backend/app/api/v1/__pycache__/health.cpython-311.pyc b/backend/app/api/v1/__pycache__/health.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1eebe8d982a813f9caee045aa42e21fc041b9bed GIT binary patch literal 26191 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 literal 0 HcmV?d00001 diff --git a/backend/app/api/v1/__pycache__/profile.cpython-311.pyc b/backend/app/api/v1/__pycache__/profile.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ecd3937dcfa4b0e781a585f91d2f8345e062cf3a GIT binary patch literal 24131 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 E0p|qwB>(^b literal 0 HcmV?d00001 diff --git a/backend/app/api/v1/__pycache__/users_lightning.cpython-311.pyc b/backend/app/api/v1/__pycache__/users_lightning.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..711ab1696ac429028c0abeffb7c11225172a9771 GIT binary patch literal 66125 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�^zePY=^H9mcTA3qqZr+$gcfGO6GlI)X2xPL_Z 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 M4jxjvo#|a*u}`J%)m`g+r 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 Ss`yR&L|>QW`g}-ci~k$LMCu*@ literal 0 HcmV?d00001 diff --git a/backend/app/core/__pycache__/circuit_breaker_fallback.cpython-311.pyc b/backend/app/core/__pycache__/circuit_breaker_fallback.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..215e4c90677294840baea3486c8b94382eac216d GIT binary patch literal 9833 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 GYw|z*A$~pp literal 0 HcmV?d00001 diff --git a/backend/app/core/__pycache__/database_pool.cpython-311.pyc b/backend/app/core/__pycache__/database_pool.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9bd4dab62fe9598f0e5e8fd3571ab13de84ea89d GIT binary patch literal 3449 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 B6b%3X literal 0 HcmV?d00001 diff --git a/backend/app/core/__pycache__/redis_client.cpython-311.pyc b/backend/app/core/__pycache__/redis_client.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ef5c78cd0ca493113ec0e3e0cce24add1895589 GIT binary patch literal 11555 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 Y`FH1UavO}(5nE~ixyL-}L}X_E3l_0_H2?qr literal 0 HcmV?d00001 diff --git a/backend/app/core/__pycache__/supabase_connection_pool.cpython-311.pyc b/backend/app/core/__pycache__/supabase_connection_pool.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..51d5889ec4521d3c0799b1ef4439a67982db7836 GIT binary patch literal 34857 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 G_kRF7L*!Ke literal 0 HcmV?d00001 diff --git a/backend/app/core/__pycache__/tenant_cache.cpython-311.pyc b/backend/app/core/__pycache__/tenant_cache.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3c7c284862314efd427c4a3c8e73581c44421c47 GIT binary patch literal 5097 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 Y^he9rD|$6NSqo3r!;|YF{BdRd2MB|O^8f$< literal 0 HcmV?d00001 diff --git a/backend/app/core/__pycache__/tenant_context.cpython-311.pyc b/backend/app/core/__pycache__/tenant_context.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..019ca3aee82997ff5854f710b80a9726b6fd85a2 GIT binary patch literal 2326 zcmb_d&2Jk;6rWv>Ke8L!X+xp0ov_e=Vh*iD0uoTA5)DE{*gga}__A7gCdFXyn%OmK zBaosBsZ}q{0jW7~@F}zkho1Ncxb(Oy?E&o-^}x+iZWRaK+x6PcHlc~cX!gzQ`HSW=q0P zjamvud=5VZ@sKzpH4cMmzp?%YvJd)$u?-6kNs+f#H@TxZU-K#8VLnjR>I=akPf67E z$Fj)6(m~4RPE`^}KO2|Up1*#@==H*X?yL{W55fm8z$r=^wk*r zP3}A<;v6g~iXeglD5jxZ03}-O^B@44`s#yg_pfe(TDaIWve&=?(Itwu;n4-3F1T@z5RN$q0cS>dB5&V~ zc{@7GH#Sa1+Zlvb00FekA%c*$QT_5r&GGRQNJzZr#vluK>v!tAA9!@pr;BdfUo7MQ z!OYc|nN#pyRy`nQ2yY%XovdLVxjDgB0hdL@7E|-WgZ2CCo?7&$BDdZ3PO zs_zY93&b2`oZCJ4F9`gR#+RNWf}*Y)rfE3_-t)GuN14aVOyI!~ctS!32~4%XeI+*k zJa@Hgv3`fIi)FAP5ABaZ4pWjO4P{xPLoyZ_B3*LHo74SIQg)B_VTQc3_Nesa^QX&h zwc%A8ezmcq-fQmV2J^q<{ruZ5X+ZZ#13as%kCZ1LJ*DnS&0DGYE43Zv-eW&p*b^isYkPHd{ literal 0 HcmV?d00001 diff --git a/backend/app/core/__pycache__/tenant_resolver.cpython-311.pyc b/backend/app/core/__pycache__/tenant_resolver.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2bea45b3e6b523d5f63a233e0d94c51ea1958db3 GIT binary patch literal 3525 zcmb_eO>Epm6dv3A@7<(rwvDq*g-cu7?N6$tO+`bCN*fxrz#{cWlt62_J5J(e*Is6w zhAcq}qK60$aAS{=kV>HkazH3T9D3-XM<-e-E1x1EB)DxABv4Ph8GF6iY!Xnx_PqIf z@6F6N-<$C_i9`&+Q!D>?XG%oq7h0)50k5!n0}5XujD`{BFrVY{{4meavXB#o1s-X_ zow_d4g7-Ou9zt@T;Si685Dwf!IC!6j9!OqK7z`WVDlNJGOMOq|Eu zu%HDnuLZH7g|u*&Z!;2r$p!91{h{AB90A?nhPt5^-6-g`;fNN-QAn|7?=V_;B!b0z z!F40Vz>3<$AqhA<62gfV&ms;3Koe~TpFRlIs1=xLV8r?%y$H|mWg5-34hk)sk8Am?LuhVIx#0!}n&%As4l;KB z6qCK@br;x;aAk1H9-KWf-{dtiS{(3e)K3%e1M;AjHL-@-=6L1}>nm(m);VywAYU4k z^$`e=2?HOMGp3=*Cd3Ju)Qg%wo|Bj;YDCFvmWowNb)s&30VABaS}6D(rF|K5?W(9# zSvTCd)>oBD3yv_VSxzWtj*e=?2~VoT(2dbFPeOnrp^;al*vj%V`8fDzDQgn#xHoP+ zu6qhoPM23vygo`%g@IE#qBK;IhGs8S+oc-f5__wivb{~Ng-|?IzG;hx;iD!-Me1LcPA^HP7mh4S7c0`m z4NP{vxSTw&lsqsuzL@N*B>QHgRWS)(qkF0y-FCeD*GStJZJ)K-oo5y!XDgAjcI0fe zy<^r|g=r!u$~J^<#>TPs9Vq#+7HN((h#uaL9{wMrhim5ZbH?E2UIGvu!P56W**1v| zx?q_uc+05pVHuFG*9~N>XW0o)rvAT>U@Rq3fSJH`hcao7#32U`@1SjKI8551!I3s1 zADwOK;J;ugRXhrAil2aRN!nRX+u}a>fG*|tDjjJ%o?a1CW!)AJ!dI2{&K<8veaq6R zCF#`sM~l*higaN;4_Cyl^1HV95`5I4ry}((OZ`hy|NQu(biN{;Z!w@0B->#Y87IuZ zhBF|>3R+&(b54+jUX~vE^@oP?r;t_$K)iuCAm%iOxp8)U5+3tcX{er4;k)mJNZ z7AK6NW}Pb#v!D@cY9wb)_GHa`DdHYn$JEj;Gpnh_<{Gz4sjO;X9il*M(fSsp1+o(m zCcCKU1W}~B0LyV1xP2W1bzG9Srk;+6sF(8~euEcymqPJfc30n$*k_A<)s8)14phaR zc31C`*lUZujfVauvELT^Spyu8+fuV7Mj93uS+?=uls@!Nfsunoj7ts-_j{TzeePp- zy+BvYc15n=LGq+-jWzC?|Gww$F2I#G;GqIHqd$WTp~oZyHv_mOxOY#m87ho7o}>Ci zONZBiyoK&97^FxqBM%>=As3^x>=aWn2DVLJp~D6gd-F!LbgGPB&kSI(M<(iq`Ob_%p$?MU<>{eYBT;@ z4P3SZmsf(@YkYSwIS)4%WDAELo%s0}D>lSa0flzld!Omm&Oo`wOTpxW!5V^W{>DP~ zhnuX}5WWQ{)J`&sWH41jARctEY+)bE9*sRIKF+hEt=wjLL-<~(?NR0>8cfWes3FK6 zx!IGGtkw{|5$H5pT}&t(=?IY_b3)cs0e)FrJj3)y25L?eerw)jKQ&|zXc4-VE{e^_ zK8u`jH}6$)5L9Rk6iXm#0>^PRp63EJL`4X3-8S02_N$_{8TPJ3Q?s3wXsZ13Vsw8c Zx_>5A3*F*4nDxf;DQo{@lU}yMzX8=bb6x-d literal 0 HcmV?d00001 diff --git a/backend/app/core/__pycache__/token_encryption.cpython-311.pyc b/backend/app/core/__pycache__/token_encryption.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9fa859ebd2fe1e39cf8ae6580d0cc009a43cadc0 GIT binary patch literal 12619 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 literal 0 HcmV?d00001 diff --git a/backend/app/models/__pycache__/profile.cpython-311.pyc b/backend/app/models/__pycache__/profile.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0eb44b5b15ddb3ef51263f04d8a0209cf5a40558 GIT binary patch literal 5815 zcmcIo&u`nv6(*&TM9Gq6*^bwCV%fEwA4+$Vw%K-*bhAb3q{(g_CCJ)Es{$2hb8K@< zi7H8L*F_5`K#Qh84mt!_9rv_F+ItWED=45Sh`ILEn+^MvQ{Q{kFOqUvEVj((^UQqY zJkGrLz8U7vxm-qq>!|a$PyV1t(!a3LzY@L5$zNni`drc^O*W*OT#;+BN~{*I#AWP@ z8LXD5Bx=b@vX-i(YDz_+{_#z~v(LCW)H_F3%@J_VUC{0au7{Q^ZXJHxn7NK-?^F=XfDB z<}`70z`YfDZicvd;1(j!%@Vf=-1*3J=ZL!i+){*_(~2KUrR9I)@|NNv{X^B}k4%jl zLb+d4b>m~l5~+ud)7Z9*5)*7ww;iE8ZaBJGR}I1L>AQ}I->n~(WT9xP!yUcGcYEHV zKYibw{1cj=OI)hRnpBBxLu^#yobklM;BKDOV(&u>m{f#`_ZTI@upX0+Fo_YY-N&KIe!dTze$nbwz>7hGWT?Y;~JJlR@3cyr zq4{c6t=CP5tl7X%BA-W?LMR|iBg`VqA1n*NfNHMuUD}j~n*&hClIZjYBJo zHzS}H*nbCTjr{XgFSRz?S2{OdzT>h>P`d1rx3JXOcs}1=d$Hs)EM2zbonLO%?FD&Sh&*x@^rWuC^XNKWN)8 zYA#!a(q*gO>;m-dx@-YTmo0d+^L~5YW%FG&?-l03-VJE@ZNFkI_a_sGXwWvgPH@?V z5v|D(2{BO^iG&S{LrRoi#VrhSYZ2i*LJ@&RU%}dHA8`3k&=JE$^O(}Q=iiIBeZ@D~ zZeVhjtu?e1vVIBs5N5EljzF)5T>*0pI`BF%0EQFamN+D`CSy8K%}?TZ1rmtIN79>V zl&Tz(TcgyZ8l@shR0Zn$= zX&EB3OG~a*RYzo+G-<2{rZMmzhWKzAs7G21jKyD1j~KhQVb=Hb{jKsV7V@IV?^$LI zMt3ZIr|EDzw6G%SKWbeEJ4^68!37@i>|*hG9{>5v{T(1n>5vWU0`yw=u=Py@OkxW+ zU<+>#8MLlo9|ESV{ab*cwU*>56RiiW2hSdOxvAD>YxCLW*p!;W9Prb?8>t^LIk9{s zMd29xPR9`bwD5HT%O8ghyiP2D;qnhRguy0|L~+*o!cSX*A3@+M+6Me6f)+`?=8Jl& zLUOMuB+sb|Nqk?(!Mzh=#&<8@;});)avKGEOH6|z>U+Ac!BvjCpC|Pj&ulQLuH5??BYn6f2gxd(;N5H9ugWu^t zwlmbsZ(M{Z=z!9~--}yUq12q^bv8*b>U_CnEb7hP8DvZ7an2WUw6i_+{H^Wy^F zED#riv>Yp|=R!Vvlc4 zAgFQ!@1V87X8Bbr9C1UrIa6fr;ur`xfs+G(KwL#dW<*534naZFfhCJW2VQURq86jg zsOLXurC@97ZAZ{jsO6s)V<0BT^~8j{xL6*Mh9{8GzHp#!2n7U#@0-@)mdKH4RC!(9 zF*xKu>cyay?@7g=BS$LHZ2$)><&jA9inJly( zwH`ft$P{RjOxLTdqU3<7v;8ebT{lD&h{ z*yBkVELaF6a>H!Ku7Kr19DD}MXf|W=M9%sDmoE*7mZUgij(x=QOXChYqscrya3oV^1O@csG~aQV&7y_X-j>|MGF zuK#IAd-)5OU4_zRSG_UM`h)l(fJOt3V9qd`4xi=wkK6SH^eK)l^BOjUcz?S@&0 zvof9^MXJVa8$Kh;rNr5C6H=9*;430v#@YB05{Rs+nbzah<7bZtr%F6q`jLSTjh_v! z$r-c3ZI+S~WH=T0dZ3dahm&9L6qulN%lAIJ`x6zZ-sh;8Xbhy<7W4HH4X=(e*=8L+ z8ZSWu^0k=a*L#M*wE|y7QH4Z zh=N=if%fz)*3gUe&F6nJ&{+|MgEn^BLP&B+P-wCg05q}Cj9)A7`~U0kfu+I#DF61K z;QQ?;F3YkfecL^|c+%VMe=DA}aPF* literal 0 HcmV?d00001 diff --git a/backend/app/monitoring/__pycache__/__init__.cpython-311.pyc b/backend/app/monitoring/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d6b275def06fd9bee494b8c74f78aa8f42447d42 GIT binary patch literal 486 zcmb`Cu};G<5Qfi58V5>MsfZOibm>ARX2ix=1Y+}YieeK5;>0-aP$u32W){Q?@EnZD zD-&C!Zk@29Rr>&(7UB(UCo4^PleG%*4X}e#Z_HYW__@)HqN+mwq2v0G2Z)5dyor*+p5N-rnwmJ zSc=H&4AFMCu65}Cq9c!vN9;j85(nRtmL=jFEL;i8qe-gN@7|0xK`h*eh{tNaOipFZ pXQepPeW&+>Hp-z52_c^_`hZazQ4+N9e;ClN_gmqS`lWmB(H~hrhD-ne literal 0 HcmV?d00001 diff --git a/backend/app/monitoring/__pycache__/middleware.cpython-311.pyc b/backend/app/monitoring/__pycache__/middleware.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1194edfb49f2e0b037502fc7f5b9f7141c745e4b GIT binary patch literal 2691 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 z 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 literal 0 HcmV?d00001 diff --git a/backend/app/services/__pycache__/cache.cpython-311.pyc b/backend/app/services/__pycache__/cache.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f55e7016ea52b3c1276ed10c41dd677a31a2f51d GIT binary patch literal 1459 zcmZ`2OK2NMbY_40Sy58CbyD22u0ug>A{COh#3}ih)L@$CU^focMJ&7Hc$NK#*^#N_ zH3(9A$~}fq5T&>-Nl%61V-G#}xH1BZfkL5|_9igB_|!KmuWN<$?R)dyyq))-`5~Xr zB7n+^U+O>02>mHG38asO!yOQwA`4mALDdn*u2hw=kR?ZP)vD@hRW06QCsj=mxt>^~ zZYFVfnoEeJ>TztLwPZ`#mJoUlG=gmmJD?F%bCyabEDb0{KqA_zbRqePRy8aAwNlMn zco~&4e+&J+lEjrew#m4B+iUU6(x-P8muvTz?zYcUV%fo5rQ-Oe;jH-qoBQa>$JZ(! z@LYrX4MJI~W?MYNh-Y|Ah#DoVNj>uCC zzZ2-5RFY@}52f)cA44BD!{a?=vOr+Fw@+E{c^aSWk49(^0~dVZ4I={OjLDoiBRzMItn76>!fNT5@) zPP``3gQn{mv~@{uGTX7+w)aps4RcL!=Igc#<5(v;Ok~xkuHl)a9J^_!j~&b%;kkQM zOr?bR6b#dBItC*(<}<^o9UrnULF-FtJ`s<-W;!lzUt&s&>o1p2i zK%5li>-y1~6^Ig35~&hflp8Hxgp`t`YsamjQ(!BePp}WmU+{I%FpbWAxOFW$dlj&| zG2)%Ye>60y9~5Wzi?iLuUa{OSmZSX3*jX5)@}7BDv$rDU75GQ)T<7ycs0x+N&@;ezKAuq72wI+L`#hBhYOLoPYc=3%P;t|!A`B!y z;Odfi%{;wIeYe)64%eWK#9OBm;)EP98u#!=M9&MmH()tRf8zR9(;+wLENsQg48DV9 zC}WHVDA$R<0eUMM#{rs-UWEgc>BJwj>+I`KHVz82`vn+6cmDguok!92`@M@R{fjHT n!h?R{L1$v9Oybvet_%^d-4Xls>Ylu}yqEs%My&ncC9dILgLrfB literal 0 HcmV?d00001 diff --git a/backend/app/services/__pycache__/reservations.cpython-311.pyc b/backend/app/services/__pycache__/reservations.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7509e8e23838f9f0417f3ef0e850930a8ebdc13c GIT binary patch literal 3839 zcmbtXU2Gf25#Hn7k;h+|p=5~`Wvwi#5+#9>o2Et_TY*e5brMr*EV)h87A(s<$yCTA zyLXBsmI{P82-qS;Q#Xa2rbXF@x(ZyNEzlNzDG{v`U$F(v z714@abODb`bT6Wa=K&p$Fq$ByR7uU`BxpP4q;w{i%0^g?o6DqCjh&S@H10x1Q8jmg zo}Hwz*+_@ zM4KGcEVXo#XOK$y_EL#0*+lLJi_lFdM%uK)82`H7Aw8YkMVRT3amd|PPLVVCIyp;R zrG3|Xt0Gk5*LbsY11z`+#Yk7-oPNN518uYKa+`t^m4u4joNKQ|dkK}8lD*`(0h(^M zv{~exAl>!__T_It^Jc5tF2f*saG0+8U&~!VZ?dnUD@@5rPN@Eta-;_K+a;&y*!LZ) z<<_3;Yu6zP)>-g1XYt!E3@Mh%rq{FJZVD#S8L1rz3cF5$l5%;TJA0B9!84%Y>HkZ^8H~eU zv1rhE{i|xsbi}1OQp$#$F05*S+#GxfccA|=;J zRufhvHGP@nuV{Qan}@TY_f}&Sl|)=bpwdoCXoMwhO1debYBiUlriiMWtqGDW8ZC~l zqp_e-p+dTw=;Vu`DcG1^=#gjAk}}nP`q9FM76gYhygI3SZ+0WO=iCH?GJ4yU1UTV8 z;kSjF0^$Q(^Yqu?hO5^6nLl_vT;VIWhQm`PZx^?U_X7Rb=PDyRL%)ga zyiyBH)dN#yp)7o+51;(-d?mHxuLUORfr+wk-`}@Acx|xKS0DOn&3~%yKUH-f%v*C! zo1gD*boXs1t|gi_!F#0n6!P{pJUtE1(T1n{^L}5C>k$IdM82-alQP@Hs4MW3wI8kh zF#BG%DjYjB@0P_Uvh42Ok4#qGGe17{^QYfeuAlm#R11XbfpE<|Qg@G3-6MY)y*2!& z$v;n4xfzAt?c348b7Sb!u~3X-(=-N{i5~w|C=Z+P-3`QXnwVp2VGhfnlC9Fh7gLzl zC3dZa1=eWR9)CAEi1}Ql70=r>h#ZaiRs^%i@*sIAT0Ak{{||Dlc+ZowD!mAMsXcC& zc#;3l;yoZS*k+NnTfY(@9^Z~0qVP+85m718Dca!#^!_kXpE7rXP#BTpn+~;Se?)YZ z&__sgml&X)lH()vs{`vW=xxB@O~+e~D~xGl#9N%uBhKvVDv?&LXhZTjY{rsy@E|@| zHud~Lte`=_zza(ZGXq3hSf4zUfntjVSs+aB!HO9q4i}6qT$*1R8;_VPK@Ea!p(mN9 zNY$}u2R?Oh7--VAa|#nDb@XV#&tb@c@z*XcT>3gb_nL`s^dZ=xUh^9E?u9^&y|g%| z`8zfq;oAZ=bplODuM;B4=?w_#)U+Zu9i5&o2Ilr6Kb8oAw*q}H6kT}C*z0LrWFx0> z#BGFl>N^H}9Hp&ZO8O|FeyyVfIR-7w8Gkb^6)1jde1T*D@rAbSw9tYKP_g5boSD*&x8!p!QTDwZ?T+=!|WIojp*;`&X1q^CqiMtTaQWVGMi)DSrdfWEqBO zpn Dict[str, Any """ Fetches revenue summary, utilizing caching to improve performance. """ - cache_key = f"revenue:{property_id}" + cache_key = f"revenue:{tenant_id}:{property_id}" # Try to get from cache cached = await redis_client.get(cache_key) diff --git a/backend/app/services/reservations.py b/backend/app/services/reservations.py index 384bd00ab..a7177f26f 100644 --- a/backend/app/services/reservations.py +++ b/backend/app/services/reservations.py @@ -2,108 +2,85 @@ from decimal import Decimal from typing import Dict, Any, List -async def calculate_monthly_revenue(property_id: str, month: int, year: int, db_session=None) -> Decimal: +async def calculate_monthly_revenue(property_id: str, tenant_id: str, month: int, year: int) -> Decimal: """ - Calculates revenue for a specific month. + Calculates revenue for a specific month, respecting the property's local timezone. """ + import asyncpg + from app.config import settings start_date = datetime(year, month, 1) if month < 12: end_date = datetime(year, month + 1, 1) else: end_date = datetime(year + 1, 1, 1) - - print(f"DEBUG: Querying revenue for {property_id} from {start_date} to {end_date}") - # SQL Simulation (This would be executed against the actual DB) - query = """ - SELECT SUM(total_amount) as total - FROM reservations - WHERE property_id = $1 - AND tenant_id = $2 - AND check_in_date >= $3 - AND check_in_date < $4 - """ - - # In production this query executes against a database session. - # result = await db.fetch_val(query, property_id, tenant_id, start_date, end_date) - # return result or Decimal('0') - - return Decimal('0') # Placeholder for now until DB connection is finalized + conn = await asyncpg.connect(settings.database_url) + try: + row = await conn.fetchrow( + """ + SELECT COALESCE(SUM(r.total_amount), 0) AS total + FROM reservations r + JOIN properties p ON r.property_id = p.id AND r.tenant_id = p.tenant_id + WHERE r.property_id = $1 + AND r.tenant_id = $2 + AND (r.check_in_date AT TIME ZONE p.timezone) >= $3 + AND (r.check_in_date AT TIME ZONE p.timezone) < $4 + """, + property_id, + tenant_id, + start_date, + end_date, + ) + finally: + await conn.close() + + return Decimal(str(row["total"])) if row else Decimal("0") async def calculate_total_revenue(property_id: str, tenant_id: str) -> Dict[str, Any]: """ Aggregates revenue from database. """ try: - # Import database pool - from app.core.database_pool import DatabasePool - - # Initialize pool if needed - db_pool = DatabasePool() - await db_pool.initialize() - - if db_pool.session_factory: - async with db_pool.get_session() as session: - # Use SQLAlchemy text for raw SQL - from sqlalchemy import text - - query = text(""" - SELECT - property_id, - SUM(total_amount) as total_revenue, - COUNT(*) as reservation_count - FROM reservations - WHERE property_id = :property_id AND tenant_id = :tenant_id - GROUP BY property_id - """) - - result = await session.execute(query, { - "property_id": property_id, - "tenant_id": tenant_id - }) - row = result.fetchone() - - if row: - total_revenue = Decimal(str(row.total_revenue)) - return { - "property_id": property_id, - "tenant_id": tenant_id, - "total": str(total_revenue), - "currency": "USD", - "count": row.reservation_count - } - else: - # No reservations found for this property - return { - "property_id": property_id, - "tenant_id": tenant_id, - "total": "0.00", - "currency": "USD", - "count": 0 - } + import asyncpg + from app.config import settings + + conn = await asyncpg.connect(settings.database_url) + try: + row = await conn.fetchrow( + """ + SELECT + property_id, + SUM(total_amount) AS total_revenue, + COUNT(*) AS reservation_count + FROM reservations + WHERE property_id = $1 AND tenant_id = $2 + GROUP BY property_id + """, + property_id, + tenant_id, + ) + finally: + await conn.close() + + if row: + total_revenue = Decimal(str(row["total_revenue"])) + return { + "property_id": property_id, + "tenant_id": tenant_id, + "total": str(total_revenue), + "currency": "USD", + "count": row["reservation_count"], + } else: - raise Exception("Database pool not available") - + return { + "property_id": property_id, + "tenant_id": tenant_id, + "total": "0.00", + "currency": "USD", + "count": 0, + } + except Exception as e: print(f"Database error for {property_id} (tenant: {tenant_id}): {e}") - - # Create property-specific mock data for testing when DB is unavailable - # This ensures each property shows different figures - mock_data = { - 'prop-001': {'total': '1000.00', 'count': 3}, - 'prop-002': {'total': '4975.50', 'count': 4}, - 'prop-003': {'total': '6100.50', 'count': 2}, - 'prop-004': {'total': '1776.50', 'count': 4}, - 'prop-005': {'total': '3256.00', 'count': 3} - } - - mock_property_data = mock_data.get(property_id, {'total': '0.00', 'count': 0}) - - return { - "property_id": property_id, - "tenant_id": tenant_id, - "total": mock_property_data['total'], - "currency": "USD", - "count": mock_property_data['count'] - } + raise