fix: tenant cache contamination, DB pool & mock fallback, timezone month bounds, money rounding, and auth refresh - #194
Open
VoidClancy wants to merge 7 commits into
Open
Conversation
- key revenue:{tenant}:{prop}:{period} instead of revenue:{prop}
- validate tenant and property on hit, wrap Redis get/setex in try
- add PHONY to makefile, and run command to rebuild on run
- add pycache to gitignore
- Fix DSN from settings.database_url with asyncpg normalizer, remove QueuePool - Make get_session sync instead of async, and pool initialization idempotent with lock
- Define to_money() to return money rounded rounded to exactly 2 decimal places - Define month_bounds() to calculate the start and end of a calendar month - Define calculate_revenue() to calculate property revenue using half-open monthly bounds in the property's timezone, with AT TIME ZONE p.timezone for correct local-date filtering and a LEFT JOIN to include properties with no reservations - Remove mock fallback - Define list_properties() to return all properties belonging to a tenant, filtering by tenant_id and ordering the results by property ID - Update cache to use the newly implemented calculate_revenue(), passing the requested month and year to ensure period-specific revenue is calculated and cached correctly
…gin for issuing tokens
…B error - Define GET /dashboard/properties, uses _require_tenant(), calls list_properties() and returns proper http codes - Update /dashboard/summary to include optional month and year. used for filtering in the frontend, also uses _require_tenant() to get authenticated tenant id, returns more fields required for filtering - Reverse checking order in tenant resolver, using app metadata first, fall back to email map (user metadata), and lastly none - Define getDashboardProperties() in secureApi, to get property insights for the dashboard, calls the implemented route in dashboard.py - Keep hardcoded properites in the dashboard ONLY for fallback, call SecureAPI.getDashboardProperties() in use effect, set properties, and render them - Add a date picker to filter properties by month, to match the filtering logic done in the backend
- Define unauthenticated refresh-session in persistent_auth.py that decodes expired JWT, auto-provisions session and mints fresh token with extended exp - Make persistent_sessions tolerant to missing table and return in-memory fallback - Add localAuthClient.refreshSession + sessionValidator/profileService fallbacks to localStorage token with 401/logout vs 5xx/preserve and tenant extraction via app_metadata - Fix tenant handling to app_metadata first in jwtUtils/sessionManager/secureApi and accept slug tenant IDs, fix header merge and same-token guard - Fix apiBase localhost fallback for profile page in dev - Fix nginx.conf to proxy /api/, /health, /up to http://backend:8000 to prevent SPA fallback returning <!DOCTYPE html> for relative fetches
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Backend
cache: key revenue:{tenant}:{prop}:{period} with guard, wrap Redis get/setex
db pool: use settings.database_url via _async_database_url, remove QueuePool, def get_session sync, Lock idempotent, main falls back to db_pool only if supabase_pool fails
reservations: single calculate_revenue with AT TIME ZONE p.timezone half-open month_bounds, to_money quantize ROUND_HALF_UP string, left join COALESCE, remove mock fallback, add list_properties
dashboard: GET /dashboard/properties tenant filtered, summary takes month/year together, _require_tenant 403, 404 if not tenant, 503 on DB error, return property_name/timezone/period
tenant_resolver: app_metadata first, decode JWT verify_exp False, email map lower, None not tenant-a
auth: cache exp check is_token_unexpired, persistent_auth add jwt/settings import and mint new exp, login uses access_token_expire_timedelta 60s
Frontend
secureApi: app_metadata tenant, slug isValidTenantId, waitForSession base360-auth-token, header merge fix, oldToken stale check, month/year wiring, getDashboardProperties
localAuthClient: getSession load only, refreshPromise dedup returning AuthResponse
Dashboard loads tenant properties via API with month picker, RevenueSummary formats string money, profileService parses base360 token
nginx: proxy /api/ /health /up to http://backend:8000 to fix profile <!DOCTYPE JSON error, apiBase localhost fallback http://localhost:8000
Video