"""Booking service — async layer between handlers and DB.""" from app.db.postgres import PostgresDB from app.db.memory import ( create_booking as json_create_booking, get_busy_times as json_get_busy_times, get_user_bookings as json_get_user_bookings, cancel_booking as json_cancel_booking, update_booking as json_update_booking, load_bookings as json_load_bookings, save_bookings as json_save_bookings, USE_POSTGRES, ) from app.logger import logger async def create_booking(user_id, service, master, date, time, user_name=""): if USE_POSTGRES: booking = await PostgresDB.create_booking(user_id, service, master, date, time, user_name) return {"id": booking["id"], "user_id": booking["user_id"], "service": booking["service"], "master": booking["master"], "date": booking["date"], "time": booking["time"], "status": booking["status"]} return json_create_booking(user_id, service, master, date, time, user_name) async def get_busy_times(master, date): if USE_POSTGRES: return await PostgresDB.get_busy_times(master, date) return json_get_busy_times(master, date) async def get_user_bookings(user_id): if USE_POSTGRES: bookings = await PostgresDB.get_user_bookings(user_id) return [{"id": b["id"], "user_id": b["user_id"], "service": b["service"], "master": b["master"], "date": b["date"], "time": b["time"], "status": b["status"]} for b in bookings] return json_get_user_bookings(user_id) async def cancel_booking(booking_id): if USE_POSTGRES: return await PostgresDB.cancel_booking(booking_id) return json_cancel_booking(booking_id) async def update_booking(booking_id, service, master, date, time): if USE_POSTGRES: result = await PostgresDB.update_booking(booking_id, service, master, date, time) if result: return {"id": result["id"], "service": result["service"], "master": result["master"], "date": result["date"], "time": result["time"]} return None return json_update_booking(booking_id, service, master, date, time) async def is_slot_busy(master, date, time): busy = await get_busy_times(master, date) return time in busy async def cleanup_cancelled(): """Remove cancelled bookings older than the head (keep only last 5 cancelled per user).""" if USE_POSTGRES: # Postgres handles this with status column, no cleanup needed pass else: bookings = json_load_bookings() active = [b for b in bookings if b["status"] == "active"] cancelled = [b for b in bookings if b["status"] == "cancelled"] from collections import defaultdict by_user = defaultdict(list) for b in cancelled: by_user[b["user_id"]].append(b) keep_ids = set() for uid, user_cancel in by_user.items(): user_cancel.sort(key=lambda x: x.get("id", 0), reverse=True) for b in user_cancel[:5]: keep_ids.add(b["id"]) bookings = active + [b for b in cancelled if b["id"] in keep_ids] json_save_bookings(bookings) removed = len(cancelled) - len(keep_ids) if removed > 0: logger.info("Cleaned up {n} old cancelled bookings", n=removed)