From 0987abb7e307550ea2017862d06f6af836960158 Mon Sep 17 00:00:00 2001 From: exedis Date: Mon, 13 Jul 2026 19:23:35 +0300 Subject: [PATCH 1/5] fix hardcoded frontend properties --- backend/app/api/v1/properties.py | 24 +++++++++++++++++++++++ backend/app/main.py | 2 ++ frontend/src/components/Dashboard.tsx | 28 +++++++++++++++------------ 3 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 backend/app/api/v1/properties.py diff --git a/backend/app/api/v1/properties.py b/backend/app/api/v1/properties.py new file mode 100644 index 000000000..4b262f0ea --- /dev/null +++ b/backend/app/api/v1/properties.py @@ -0,0 +1,24 @@ +from fastapi import APIRouter, Depends +from typing import Dict, Any, List +from sqlalchemy import text +from app.core.auth import authenticate_request as get_current_user +from app.core.database_pool import DatabasePool + +router = APIRouter() + +@router.get("/properties") +async def list_properties( + current_user: dict = Depends(get_current_user), +) -> List[Dict[str, Any]]: + + tenant_id = getattr(current_user, "tenant_id", "default_tenant") or "default_tenant" + + db_pool = DatabasePool() + await db_pool.initialize() + + async with await db_pool.get_session() as session: + result = await session.execute( + text("SELECT id, name FROM properties WHERE tenant_id = :tenant_id ORDER BY name"), + {"tenant_id": tenant_id} + ) + return [{"id": row.id, "name": row.name} for row in result.fetchall()] diff --git a/backend/app/main.py b/backend/app/main.py index 00734b2fa..204b208a5 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -29,6 +29,7 @@ persistent_auth, dashboard, login, + properties, ) from .monitoring.middleware import PerformanceMonitoringMiddleware @@ -183,6 +184,7 @@ async def lifespan(app: FastAPI): # Dashboard app.include_router(dashboard.router, prefix="/api/v1", tags=["dashboard"]) +app.include_router(properties.router, prefix="/api/v1", tags=["properties"]) # Bootstrap & Settings (for AppContext) app.include_router(company_settings.router, prefix="/api/v1", tags=["company-settings"]) diff --git a/frontend/src/components/Dashboard.tsx b/frontend/src/components/Dashboard.tsx index a21bba404..f8908c800 100644 --- a/frontend/src/components/Dashboard.tsx +++ b/frontend/src/components/Dashboard.tsx @@ -1,16 +1,20 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { RevenueSummary } from "./RevenueSummary"; - -const PROPERTIES = [ - { id: 'prop-001', name: 'Beach House Alpha' }, - { id: 'prop-002', name: 'City Apartment Downtown' }, - { id: 'prop-003', name: 'Country Villa Estate' }, - { id: 'prop-004', name: 'Lakeside Cottage' }, - { id: 'prop-005', name: 'Urban Loft Modern' } -]; +import { SecureAPI } from "../lib/secureApi"; const Dashboard: React.FC = () => { - const [selectedProperty, setSelectedProperty] = useState('prop-001'); + const [properties, setProperties] = useState<{ id: string; name: string }[]>([]); + const [selectedProperty, setSelectedProperty] = useState(''); + + useEffect(() => { + SecureAPI.getAllProperties().then((res) => { + const list = res?.data || []; + setProperties(list); + if (list.length > 0) { + setSelectedProperty(list[0].id); + } + }); + }, []); return (
@@ -35,7 +39,7 @@ const Dashboard: React.FC = () => { onChange={(e) => setSelectedProperty(e.target.value)} className="block w-full sm:w-auto min-w-[200px] px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 text-sm" > - {PROPERTIES.map((property) => ( + {properties.map((property) => ( @@ -46,7 +50,7 @@ const Dashboard: React.FC = () => {
- + {selectedProperty && }
From 2223df3f4f71fee9c4bf3fb6b85c3fdcc583081f Mon Sep 17 00:00:00 2001 From: exedis Date: Mon, 13 Jul 2026 19:23:45 +0300 Subject: [PATCH 2/5] fix invalid cache key --- backend/app/services/cache.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/services/cache.py b/backend/app/services/cache.py index b81474957..672e3f9d6 100644 --- a/backend/app/services/cache.py +++ b/backend/app/services/cache.py @@ -10,7 +10,7 @@ async def get_revenue_summary(property_id: str, tenant_id: str) -> 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) From c3347a3f5b75c69e1aeb86799e11e2baa86975ba Mon Sep 17 00:00:00 2001 From: exedis Date: Mon, 13 Jul 2026 19:24:04 +0300 Subject: [PATCH 3/5] fix missing await on async func --- backend/app/services/reservations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/services/reservations.py b/backend/app/services/reservations.py index 384bd00ab..f6c72c47c 100644 --- a/backend/app/services/reservations.py +++ b/backend/app/services/reservations.py @@ -44,7 +44,7 @@ async def calculate_total_revenue(property_id: str, tenant_id: str) -> Dict[str, await db_pool.initialize() if db_pool.session_factory: - async with db_pool.get_session() as session: + async with await db_pool.get_session() as session: # Use SQLAlchemy text for raw SQL from sqlalchemy import text From 7278631b30ac3a85b14f2d03ae6b33629080ed57 Mon Sep 17 00:00:00 2001 From: exedis Date: Mon, 13 Jul 2026 19:24:19 +0300 Subject: [PATCH 4/5] fix wrong db_url used --- backend/app/core/database_pool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/core/database_pool.py b/backend/app/core/database_pool.py index d638dfcfe..d1d289d1a 100644 --- a/backend/app/core/database_pool.py +++ b/backend/app/core/database_pool.py @@ -15,7 +15,7 @@ async def initialize(self): """Initialize database connection pool""" try: # Create async engine with connection pooling - 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}" + database_url = settings.database_url.replace("postgresql://", "postgresql+asyncpg://", 1) self.engine = create_async_engine( database_url, From 7a434b4fd652089fa6f57d1d8e04ad789684cf51 Mon Sep 17 00:00:00 2001 From: exedis Date: Mon, 13 Jul 2026 19:24:47 +0300 Subject: [PATCH 5/5] fix removing QueuePool for async context --- backend/app/core/database_pool.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/backend/app/core/database_pool.py b/backend/app/core/database_pool.py index d1d289d1a..9b674640c 100644 --- a/backend/app/core/database_pool.py +++ b/backend/app/core/database_pool.py @@ -1,6 +1,5 @@ import asyncio from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker -from sqlalchemy.pool import QueuePool import logging from ..config import settings @@ -19,7 +18,6 @@ async def initialize(self): self.engine = create_async_engine( database_url, - poolclass=QueuePool, pool_size=20, # Number of connections to maintain max_overflow=30, # Additional connections when needed pool_pre_ping=True, # Validate connections