teljes backend_mentés
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/api/v1/endpoints/admin.py
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, Body
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, Body, BackgroundTasks
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select, func, text, delete
|
||||
from typing import List, Any, Dict, Optional
|
||||
@@ -358,4 +358,197 @@ async def approve_staged_service(
|
||||
"status": "success",
|
||||
"message": f"Service staging {staging_id} approved.",
|
||||
"service_name": staging.service_name
|
||||
}
|
||||
|
||||
|
||||
# ==================== EPIC 10: ADMIN FRONTEND API ENDPOINTS ====================
|
||||
|
||||
from app.workers.service.validation_pipeline import ValidationPipeline
|
||||
from app.models.marketplace.service import ServiceProfile
|
||||
from app.models.gamification.gamification import GamificationProfile
|
||||
|
||||
|
||||
class LocationUpdate(BaseModel):
|
||||
latitude: float = Field(..., ge=-90, le=90)
|
||||
longitude: float = Field(..., ge=-180, le=180)
|
||||
|
||||
|
||||
class PenaltyRequest(BaseModel):
|
||||
penalty_level: int = Field(..., ge=-10, le=-1, description="Negatív szint (-1 a legkisebb, -10 a legnagyobb büntetés)")
|
||||
reason: str = Field(..., min_length=5, max_length=500)
|
||||
|
||||
|
||||
@router.post("/services/{service_id}/trigger-ai", tags=["AI Pipeline"])
|
||||
async def trigger_ai_pipeline(
|
||||
service_id: int,
|
||||
background_tasks: BackgroundTasks,
|
||||
current_admin: User = Depends(deps.get_current_admin),
|
||||
db: AsyncSession = Depends(deps.get_db)
|
||||
):
|
||||
"""
|
||||
AI Pipeline manuális indítása egy adott szerviz profilra.
|
||||
|
||||
A végpont azonnal visszatér, és a validációt háttérfeladatként futtatja.
|
||||
"""
|
||||
# Ellenőrizzük, hogy létezik-e a szerviz profil
|
||||
stmt = select(ServiceProfile).where(ServiceProfile.id == service_id)
|
||||
result = await db.execute(stmt)
|
||||
profile = result.scalar_one_or_none()
|
||||
|
||||
if not profile:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Service profile not found with ID: {service_id}"
|
||||
)
|
||||
|
||||
# Háttérfeladat hozzáadása
|
||||
background_tasks.add_task(run_validation_pipeline, service_id)
|
||||
|
||||
# Audit log
|
||||
audit_log = SecurityAuditLog(
|
||||
user_id=current_admin.id,
|
||||
action="trigger_ai_pipeline",
|
||||
target_service_id=service_id,
|
||||
details=f"AI pipeline manually triggered for service {service_id}",
|
||||
is_critical=False,
|
||||
ip_address="admin_api"
|
||||
)
|
||||
db.add(audit_log)
|
||||
await db.commit()
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"message": f"AI pipeline started for service {service_id}",
|
||||
"service_name": profile.service_name,
|
||||
"note": "Validation runs in background, check logs for results."
|
||||
}
|
||||
|
||||
|
||||
async def run_validation_pipeline(profile_id: int):
|
||||
"""Háttérfeladat a ValidationPipeline futtatásához."""
|
||||
try:
|
||||
pipeline = ValidationPipeline()
|
||||
success = await pipeline.run(profile_id)
|
||||
logger = logging.getLogger("Service-AI-Pipeline")
|
||||
if success:
|
||||
logger.info(f"Pipeline successful for profile {profile_id}")
|
||||
else:
|
||||
logger.warning(f"Pipeline failed for profile {profile_id}")
|
||||
except Exception as e:
|
||||
logger.error(f"Pipeline error for profile {profile_id}: {e}")
|
||||
|
||||
|
||||
@router.patch("/services/{service_id}/location", tags=["Service Management"])
|
||||
async def update_service_location(
|
||||
service_id: int,
|
||||
location: LocationUpdate,
|
||||
current_admin: User = Depends(deps.get_current_admin),
|
||||
db: AsyncSession = Depends(deps.get_db)
|
||||
):
|
||||
"""
|
||||
Szerviz térképes mozgatása (Koordináta frissítés).
|
||||
|
||||
A Nuxt Leaflet térkép drag-and-drop funkciójához használható.
|
||||
"""
|
||||
stmt = select(ServiceProfile).where(ServiceProfile.id == service_id)
|
||||
result = await db.execute(stmt)
|
||||
profile = result.scalar_one_or_none()
|
||||
|
||||
if not profile:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Service profile not found with ID: {service_id}"
|
||||
)
|
||||
|
||||
# Frissítjük a koordinátákat
|
||||
profile.latitude = location.latitude
|
||||
profile.longitude = location.longitude
|
||||
profile.updated_at = datetime.now()
|
||||
|
||||
# Audit log
|
||||
audit_log = SecurityAuditLog(
|
||||
user_id=current_admin.id,
|
||||
action="update_service_location",
|
||||
target_service_id=service_id,
|
||||
details=f"Service location updated to lat={location.latitude}, lon={location.longitude}",
|
||||
is_critical=False,
|
||||
ip_address="admin_api"
|
||||
)
|
||||
db.add(audit_log)
|
||||
await db.commit()
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"message": f"Service location updated for {service_id}",
|
||||
"latitude": location.latitude,
|
||||
"longitude": location.longitude
|
||||
}
|
||||
|
||||
|
||||
@router.patch("/users/{user_id}/penalty", tags=["Gamification Admin"])
|
||||
async def apply_gamification_penalty(
|
||||
user_id: int,
|
||||
penalty: PenaltyRequest,
|
||||
current_admin: User = Depends(deps.get_current_admin),
|
||||
db: AsyncSession = Depends(deps.get_db)
|
||||
):
|
||||
"""
|
||||
Gamification büntetés kiosztása egy felhasználónak.
|
||||
|
||||
Negatív szintek alkalmazása a frissen létrehozott Gamification rendszerben.
|
||||
"""
|
||||
# Ellenőrizzük, hogy létezik-e a felhasználó
|
||||
user_stmt = select(User).where(User.id == user_id)
|
||||
user_result = await db.execute(user_stmt)
|
||||
user = user_result.scalar_one_or_none()
|
||||
|
||||
if not user:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"User not found with ID: {user_id}"
|
||||
)
|
||||
|
||||
# Megkeressük a felhasználó gamification profilját (vagy létrehozzuk)
|
||||
gamification_stmt = select(GamificationProfile).where(GamificationProfile.user_id == user_id)
|
||||
gamification_result = await db.execute(gamification_stmt)
|
||||
gamification = gamification_result.scalar_one_or_none()
|
||||
|
||||
if not gamification:
|
||||
# Ha nincs profil, létrehozzuk alapértelmezett értékekkel
|
||||
gamification = GamificationProfile(
|
||||
user_id=user_id,
|
||||
level=0,
|
||||
xp=0,
|
||||
reputation_score=100,
|
||||
created_at=datetime.now(),
|
||||
updated_at=datetime.now()
|
||||
)
|
||||
db.add(gamification)
|
||||
await db.flush()
|
||||
|
||||
# Alkalmazzuk a büntetést (negatív szint módosítása)
|
||||
# A level mező lehet negatív is a büntetések miatt
|
||||
new_level = gamification.level + penalty.penalty_level
|
||||
gamification.level = new_level
|
||||
gamification.updated_at = datetime.now()
|
||||
|
||||
# Audit log
|
||||
audit_log = SecurityAuditLog(
|
||||
user_id=current_admin.id,
|
||||
action="apply_gamification_penalty",
|
||||
target_user_id=user_id,
|
||||
details=f"Gamification penalty applied: level change {penalty.penalty_level}, reason: {penalty.reason}",
|
||||
is_critical=False,
|
||||
ip_address="admin_api"
|
||||
)
|
||||
db.add(audit_log)
|
||||
await db.commit()
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"message": f"Gamification penalty applied to user {user_id}",
|
||||
"user_id": user_id,
|
||||
"penalty_level": penalty.penalty_level,
|
||||
"new_level": new_level,
|
||||
"reason": penalty.reason
|
||||
}
|
||||
Reference in New Issue
Block a user