Split cart into 4 microservices: relations, likes, orders, page-config→blog
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
Phase 1 - Relations service (internal): owns ContainerRelation, exposes get-children data + attach/detach-child actions. Retargeted events, blog, market callers from cart to relations. Phase 2 - Likes service (internal): unified Like model replaces ProductLike and PostLike with generic target_type/target_slug/target_id. Exposes is-liked, liked-slugs, liked-ids data + toggle action. Phase 3 - PageConfig → blog: moved ownership to blog with direct DB queries, removed proxy endpoints from cart. Phase 4 - Orders service (public): owns Order/OrderItem + SumUp checkout flow. Cart checkout now delegates to orders via create-order action. Webhook/return routes and reconciliation moved to orders. Phase 5 - Infrastructure: docker-compose, deploy.sh, Dockerfiles updated for all 3 new services. Added orders_url helper and factory model imports. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,7 @@ from quart import (
|
||||
)
|
||||
from sqlalchemy import select, func, update
|
||||
|
||||
from models.market import Product, ProductLike
|
||||
from models.market import Product
|
||||
from ..browse.services.slugs import canonical_html_slug
|
||||
from ..browse.services.blacklist.product import is_product_blocked
|
||||
from ..browse.services import db_backend as cb
|
||||
@@ -18,7 +18,8 @@ from ..browse.services import _massage_product
|
||||
from shared.utils import host_url
|
||||
from shared.browser.app.redis_cacher import cache_page, clear_cache
|
||||
from ..cart.services import total
|
||||
from .services.product_operations import toggle_product_like, massage_full_product
|
||||
from shared.infrastructure.actions import call_action
|
||||
from .services.product_operations import massage_full_product
|
||||
|
||||
|
||||
def register():
|
||||
@@ -132,11 +133,10 @@ def register():
|
||||
|
||||
user_id = g.user.id
|
||||
|
||||
liked, error = await toggle_product_like(g.s, user_id, product_slug)
|
||||
|
||||
if error:
|
||||
resp = make_response(error, 404)
|
||||
return resp
|
||||
result = await call_action("likes", "toggle", payload={
|
||||
"user_id": user_id, "target_type": "product", "target_slug": product_slug,
|
||||
})
|
||||
liked = result["liked"]
|
||||
|
||||
html = await render_template(
|
||||
"_types/browse/like/button.html",
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from models.market import Product, ProductLike
|
||||
from models.market import Product
|
||||
|
||||
|
||||
def massage_full_product(product: Product) -> dict:
|
||||
@@ -44,52 +39,3 @@ def massage_full_product(product: Product) -> dict:
|
||||
return _massage_product(d)
|
||||
|
||||
|
||||
async def toggle_product_like(
|
||||
session: AsyncSession,
|
||||
user_id: int,
|
||||
product_slug: str,
|
||||
) -> tuple[bool, Optional[str]]:
|
||||
"""
|
||||
Toggle a product like for a given user using soft deletes.
|
||||
Returns (liked_state, error_message).
|
||||
- If error_message is not None, an error occurred.
|
||||
- liked_state indicates whether product is now liked (True) or unliked (False).
|
||||
"""
|
||||
from sqlalchemy import func, update
|
||||
|
||||
# Get product_id from slug
|
||||
product_id = await session.scalar(
|
||||
select(Product.id).where(Product.slug == product_slug, Product.deleted_at.is_(None))
|
||||
)
|
||||
if not product_id:
|
||||
return False, "Product not found"
|
||||
|
||||
# Check if like exists (not deleted)
|
||||
existing = await session.scalar(
|
||||
select(ProductLike).where(
|
||||
ProductLike.user_id == user_id,
|
||||
ProductLike.product_slug == product_slug,
|
||||
ProductLike.deleted_at.is_(None),
|
||||
)
|
||||
)
|
||||
|
||||
if existing:
|
||||
# Unlike: soft delete the like
|
||||
await session.execute(
|
||||
update(ProductLike)
|
||||
.where(
|
||||
ProductLike.user_id == user_id,
|
||||
ProductLike.product_slug == product_slug,
|
||||
ProductLike.deleted_at.is_(None),
|
||||
)
|
||||
.values(deleted_at=func.now())
|
||||
)
|
||||
return False, None
|
||||
else:
|
||||
# Like: add a new like
|
||||
new_like = ProductLike(
|
||||
user_id=user_id,
|
||||
product_slug=product_slug,
|
||||
)
|
||||
session.add(new_like)
|
||||
return True, None
|
||||
|
||||
Reference in New Issue
Block a user