SxExpr is now a str subclass so it works everywhere a plain string does (join, isinstance, f-strings) while serialize() still emits it unquoted. sx_call() and all internal render functions (_render_to_sx, async_eval_to_sx, etc.) return SxExpr, eliminating the "forgot to wrap" bug class that caused the sx_content leak and list serialization bugs. - Phase 0: SxExpr(str) with .source property, __add__/__radd__ - Phase 1: sx_call returns SxExpr (drop-in, all 200+ sites unchanged) - Phase 2: async_eval_to_sx, async_eval_slot_to_sx, _render_to_sx, mobile_menu_sx return SxExpr; remove isinstance(str) workaround - Phase 3: Remove ~150 redundant SxExpr() wrappings across 45 files - Phase 4: serialize() docstring, handler return docs, ;; returns: sx Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cart App
Shopping cart, checkout, and order management service for the Rose Ash cooperative. Integrates with SumUp for payment processing.
Structure
app.py # Application factory (create_base_app + blueprints)
path_setup.py # Adds project root + app dir to sys.path
entrypoint.sh # Container entrypoint (Redis flush, start)
bp/
cart/ # Cart blueprint
global_routes.py # Add to cart, checkout, webhooks, return page
page_routes.py # Page-scoped cart and checkout
overview_routes.py # Cart overview / summary page
services/ # Business logic
checkout.py # Order creation, SumUp integration
check_sumup_status.py # Payment status polling
calendar_cart.py # Calendar entry cart queries
page_cart.py # Page-scoped cart queries
get_cart.py # Cart item queries
identity.py # Cart identity (user_id / session_id)
total.py # Price calculations
clear_cart_for_order.py # Soft-delete cart after checkout
order/ # Single order detail view
orders/ # Order listing view
fragments/ # cart-mini fragment, account-nav-item fragment
models/ # Re-export stubs (Order, OrderItem, PageConfig)
services/ # register_domain_services() — wires cart + calendar + market
templates/ # Cart-specific templates (override shared/)
Cart identity
Cart items are keyed by user_id (logged in) or session_id (anonymous). On login, anonymous cart items are adopted to the user's account.
Cross-domain communication
services.calendar.*— claim/confirm entries for orders, adopt on loginservices.market.*— marketplace queries for page-scoped cartsservices.blog.*— post lookup for page context
Fragments served
- cart-mini — cart icon + badge count
- account-nav-item — orders link for account nav
Checkout flow
- User clicks "Checkout"
create_order_from_cart()creates Order + OrderItemsservices.calendar.claim_entries_for_order()marks entries as "ordered"- Emits
Create/rose:Orderactivity - SumUp hosted checkout created, user redirected
- SumUp webhook / return page triggers
check_sumup_status() - If PAID:
services.calendar.confirm_entries_for_order(), emitsrose:OrderPaid