All checks were successful
Build and deploy / Validate source (push) Successful in 1m18s
Build and deploy / Integration suite on a real stack (push) Successful in 2m33s
Build and deploy / Secret scan and release gate (push) Successful in 9s
Build and deploy / Publish images (push) Successful in 1m42s
FREIGHT_ADAPTER=jadlog prices "Receber em casa" through Jadlog's Simulador de Frete from the order's billed metres and value, adding production days to Jadlog's delivery time. The package weight is a base plus a weight per metre from the client, with no default: the adapter refuses to start without it and without the credentials. The cart re-quotes when the package changes, and approval quotes again from the server-priced items. The production stack takes the Jadlog settings, so the read-only probe runs from the worker's console. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
51 lines
2.2 KiB
Python
51 lines
2.2 KiB
Python
"""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))
|