"""Likes app action endpoints.""" from __future__ import annotations from quart import Blueprint, g, jsonify, request from shared.infrastructure.actions import ACTION_HEADER def register() -> Blueprint: bp = Blueprint("actions", __name__, url_prefix="/internal/actions") @bp.before_request async def _require_action_header(): if not request.headers.get(ACTION_HEADER): return jsonify({"error": "forbidden"}), 403 from shared.infrastructure.internal_auth import validate_internal_request if not validate_internal_request(): return jsonify({"error": "forbidden"}), 403 _handlers: dict[str, object] = {} @bp.post("/") async def handle_action(action_name: str): handler = _handlers.get(action_name) if handler is None: return jsonify({"error": "unknown action"}), 404 try: result = await handler() return jsonify(result) except Exception as exc: import logging logging.getLogger(__name__).exception("Action %s failed", action_name) return jsonify({"error": str(exc)}), 500 # --- toggle --- async def _toggle(): """Toggle a like. Returns {"liked": bool}.""" from sqlalchemy import select, update, func from likes.models.like import Like data = await request.get_json(force=True) user_id = data["user_id"] target_type = data["target_type"] target_slug = data.get("target_slug") target_id = data.get("target_id") filters = [ Like.user_id == user_id, Like.target_type == target_type, Like.deleted_at.is_(None), ] if target_slug is not None: filters.append(Like.target_slug == target_slug) elif target_id is not None: filters.append(Like.target_id == target_id) else: return {"error": "target_slug or target_id required"}, 400 existing = await g.s.scalar(select(Like).where(*filters)) if existing: # Unlike: soft delete await g.s.execute( update(Like).where(Like.id == existing.id).values(deleted_at=func.now()) ) return {"liked": False} else: # Like: insert new new_like = Like( user_id=user_id, target_type=target_type, target_slug=target_slug, target_id=target_id, ) g.s.add(new_like) await g.s.flush() return {"liked": True} _handlers["toggle"] = _toggle return bp