"""Health, session bootstrap and freight quoting.""" import os from fastapi import APIRouter, HTTPException, Request, Response from ..core import db from ..core.auth import client_ip, owner, new_session, rate_limit from ..core.limits import upload_limit_bytes from ..core.models import FreightEstimate from ..runtime import (ENVIRONMENT, GUEST_SESSION_LIMIT, PART_BYTES, freight, payment, require_delivery_available, storage) router = APIRouter() @router.get('/health') @router.get('/api/health') def health(): try: with db.connect() as c: c.execute('SELECT 1') storage.health() except Exception: raise HTTPException(503, 'Database or storage unavailable') return {'status': 'ok', 'environment': ENVIRONMENT, 'storage': 'minio' if ENVIRONMENT == 'local' else 'r2', 'integrations': 'fake'} @router.get('/api/session') def session(request: Request, response: Response): try: session_id = owner(request) except HTTPException: # Per source, not per deployment: keyed on the environment name this was a # single global bucket, so ~8 new visitors a minute exhausted it site-wide. rate_limit('guest-sessions', client_ip(request), GUEST_SESSION_LIMIT, 900) with db.connect() as c: session_id = new_session(c, response) return {'environment': ENVIRONMENT, 'cart_scope': str(session_id), 'part_bytes': PART_BYTES, 'max_upload_bytes': upload_limit_bytes(), 'payment_provider': payment.name, # Public by design: Mercado Pago's card form needs it in the browser. 'payment_public_key': os.environ.get('MP_PUBLIC_KEY', '') if payment.name == 'mercadopago' else '', # The delivery service the cart quotes, or none: pickup only. 'freight_service': 'jadlog' if freight.name == 'jadlog' else 'mock-standard' if ENVIRONMENT == 'local' else None} @router.post('/api/freight') def quote_freight(body: FreightEstimate): require_delivery_available(body.service) try: return freight.quote(body.service, body.postal_code, body.metres, body.declared_cents) except ValueError as exc: raise HTTPException(422, str(exc))