- Server sends sexp source text, client (sexp.js) renders everything - SexpExpr marker class for nested sexp composition in serialize() - sexp_page() HTML shell with data-mount="body" for full page loads - sexp_response() returns text/sexp for OOB/partial responses - ~app-body layout component replaces ~app-layout (no raw!) - ~rich-text is the only component using raw! (for CMS HTML content) - Fragment endpoints return text/sexp, auto-wrapped in SexpExpr - All _*_html() helpers converted to _*_sexp() returning sexp source - Head auto-hoist: sexp.js moves meta/title/link/script[ld+json] from rendered body to document.head automatically - Unknown components render warning box instead of crashing page - Component kwargs preserve AST for lazy rendering (fixes <> in kwargs) - Fix unterminated paren in events/sexp/tickets.sexpr 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