The cart-mini fragment is fetched via HTTP from the cart app, which
uses its own DB connection. Without committing first, the cart app
sees stale data (no new item). Commit the transaction, start a new
one so after_request can still commit cleanly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The shared _added.html imported _types/cart/_cart.html which only
exists in the cart app. Market now has its own _added.html that:
- Fetches cart-mini fragment for the OOB mini cart update
- Uses market's own _types/product/_cart.html macros
- Drops cart summary/show_cart (not visible on product pages)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The app-level url_value_preprocessor pops "slug" and "page_slug"
into g.post_slug, with page_slug overwriting the product slug.
Renaming the blueprint param to product_slug eliminates the
collision entirely. Views now use g.product_slug (set by blueprint
preprocessor) and have clean signatures with no **_kw hacks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of skipping resolve_product entirely for POST (leaving
g.item_data unset and breaking templates), run the full resolution
but suppress canonical-slug redirects. This sets g.item_data for
the context processor so d.slug and other template vars work.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
resolve_product skips for POST so g.item_data (and thus d) is not
set. Pass d={slug} directly in the render_template call.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
App-level preprocessor pops slug then page_slug into g.post_slug,
overwriting the product slug with the page slug ("market"). Extract
the product slug directly from the request path after "/product/".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
resolve_product's canonical slug redirect causes a 302 loop on POST
/cart/ because it redirects to the GET product detail page. POST
endpoints only need g.product_slug to look up the product — skip
the full resolution/redirect logic.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use fully qualified "market.browse.product.product_detail" instead
of "product.product_detail" which doesn't exist in the URL map.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
App-level url_value_preprocessor pops slug into g.post_slug before
the blueprint preprocessor runs, leaving values empty. Fall back to
g.post_slug so resolve_product and cart route get the slug.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
App-level url_value_preprocessor pops slug from values, so the
product blueprint's cart() never receives it. Use g.product_slug
(set by resolve_product before_request) instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New all_markets blueprint at / with paginated grid and HTMX infinite scroll
- New page_markets blueprint at /<slug>/ for page-scoped market listing
- list_marketplaces service method (via shared submodule update)
- Updated slug preprocessor to handle both /<slug>/ and /<page_slug>/<market_slug>/
- Removed inline markets_listing() route (replaced by all_markets blueprint)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Emit product.listed events when products are created
- Updated shared with federation handlers, delivery, anchoring
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update shared submodule: category selector uses slug comparison
instead of current_local_href for active state
- Keep current_local_href commented out in category_context() to
avoid overriding the base template value used by brand filters
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The category selector compares current_local_href against sub.local_href
to determine the active subcategory. This was commented out, so no
subcategory was ever highlighted.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two bugs fixed:
1. First htmx add didn't update mini cart count because the context
processor's API call couldn't see the uncommitted transaction.
Fix: pass cart_count/cart_total explicitly from the route handler.
2. Page refresh always showed cart count 0 because the internal API
call to the cart service failed to resolve cart identity correctly.
Fix: replace the API call with a direct DB query using the same
shared database and session, matching how the cart app itself works.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The _added.html template's summary macro expects calendar_total and
calendar_cart_entries from the cart/events domain. The market app has
no calendar entries, so pass a no-op function and empty list.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
g.cart was never populated in the market app — the cart loader
before_request hook was only registered in the cart microservice.
Replace the dead filter-building code with an actual query that
loads cart items inline, scoped to the current user/session.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 1-3 of decoupling:
- path_setup.py adds project root to sys.path
- Market-owned models in market/models/ (market, market_place)
- All imports updated: shared.infrastructure, shared.db, shared.browser, etc.
- MarketPlace uses container_type/container_id instead of post_id FK
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add post header row to market/index.html template chain
- Fix OOB templates to include post header on HTMX navigation
- Show market name instead of static coop_title in header
- Restore trailing slash on POST /cart/ route; fix templates to
include trailing slash in cart URLs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Templates generate URLs without trailing slash via market_url(), but
the route required one. POST requests don't get redirected by Werkzeug,
causing a 405 MethodNotAllowed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The market app doesn't have a cart blueprint registered, so url_for()
would fail. Uses the cross-app cart_url() helper instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Track which market a cart item came from by setting market_place_id
from g.market.id on new CartItem creation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Product routes import total() from cart.services — provide a minimal
copy so the market image can start independently.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split from coop monolith. Includes:
- Market/browse/product blueprints
- Product sync API
- Suma scraping pipeline
- Templates for market, browse, and product views
- Dockerfile and CI workflow for independent deployment