wahnsinn vibe

This commit is contained in:
Marek Lenczewski
2026-04-16 19:42:06 +02:00
parent 9c5da44f64
commit e3e88cc58e
127 changed files with 9456 additions and 3 deletions

View File

@@ -0,0 +1,106 @@
import json
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from sqlalchemy.orm import Session
from core.db import get_db
from core.di import get_service
from core.events import event_bus
from core.redis_client import redis_client
from core.security import get_current_user_id
from apps.cart.models import Cart, CartItem
router = APIRouter()
class AddressIn(BaseModel):
name: str
street: str
zip: str
city: str
country: str = "DE"
class CheckoutIn(BaseModel):
address: AddressIn
payment_method: str = "dummy"
class CheckoutPreview(BaseModel):
items: list[dict]
subtotal: float
total: float
@router.post("/preview", response_model=CheckoutPreview)
def preview(user_id: int = Depends(get_current_user_id), db: Session = Depends(get_db)):
cart = db.query(Cart).filter_by(user_id=user_id).first()
if not cart or not cart.items:
raise HTTPException(400, "Cart is empty")
items = []
subtotal = 0.0
for it in cart.items:
raw = redis_client.get(f"product:{it.product_id}")
if not raw:
raise HTTPException(400, f"Product {it.product_id} no longer available")
p = json.loads(raw)
line = round(float(p["price"]) * it.qty, 2)
subtotal += line
items.append({"product_id": it.product_id, "name": p["name"], "qty": it.qty, "price": float(p["price"]), "line_total": line})
return CheckoutPreview(items=items, subtotal=round(subtotal, 2), total=round(subtotal, 2))
@router.post("/confirm")
def confirm(body: CheckoutIn, user_id: int = Depends(get_current_user_id), db: Session = Depends(get_db)):
cart = db.query(Cart).filter_by(user_id=user_id).first()
if not cart or not cart.items:
raise HTTPException(400, "Cart is empty")
# Snapshot items
snapshot_items = []
subtotal = 0.0
for it in cart.items:
raw = redis_client.get(f"product:{it.product_id}")
if not raw:
raise HTTPException(400, f"Product {it.product_id} not available")
p = json.loads(raw)
line = round(float(p["price"]) * it.qty, 2)
subtotal += line
snapshot_items.append(
{
"product_id": it.product_id,
"sku": p.get("sku", ""),
"name": p.get("name", {}),
"price": float(p["price"]),
"qty": it.qty,
"line_total": line,
}
)
total = round(subtotal, 2)
payment = get_service("PaymentProvider").charge(total, "EUR", body.payment_method)
if payment["status"] != "paid":
raise HTTPException(402, "Payment failed")
event_payload = {
"user_id": user_id,
"items": snapshot_items,
"subtotal": round(subtotal, 2),
"total": total,
"currency": "EUR",
"address": body.address.model_dump(),
"payment": payment,
}
event_bus.publish("checkout.confirmed", event_payload, db=db)
# Clear cart
for it in list(cart.items):
db.delete(it)
db.commit()
# Find order id from events handler (orders-app) — pull via redis key or return event_payload
# Since the orders handler sets 'last_order_id' for this user in redis for convenience:
last = redis_client.get(f"user:{user_id}:last_order_id")
return {"ok": True, "order_id": int(last) if last else None, "payment": payment}