""" quiXzoom Management Module Handles missions, contributors, submissions, and payments """ from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from typing import List, Optional from datetime import datetime from app.database import get_db from app.models import Mission, Contributor, Submission, MissionStatus, User from app.core.security import get_current_user router = APIRouter(prefix="/quixzoom", tags=["quixzoom"]) # ─── MISSIONS ───────────────────────────────────────────────────────────────── @router.get("/missions") async def list_missions( status: Optional[MissionStatus] = None, city: Optional[str] = None, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """List all missions with optional filtering.""" query = db.query(Mission) if status: query = query.filter(Mission.status == status) if city: query = query.filter(Mission.city.ilike(f"%{city}%")) missions = query.offset(skip).limit(limit).all() return { "missions": [ { "id": m.id, "mission_id": m.mission_id, "title": m.title, "city": m.city, "country": m.country, "status": m.status.value, "reward": f"{m.reward_amount} {m.reward_currency}" if m.reward_amount else None, "start_date": m.start_date.isoformat() if m.start_date else None, "end_date": m.end_date.isoformat() if m.end_date else None, } for m in missions ], "total": query.count(), } @router.post("/missions") async def create_mission( mission_id: str, title: str, city: str, country: str, reward_amount: float, description: Optional[str] = None, requirements: Optional[List[str]] = None, start_date: Optional[datetime] = None, end_date: Optional[datetime] = None, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Create a new mission.""" mission = Mission( mission_id=mission_id, title=title, description=description, city=city, country=country, reward_amount=reward_amount, requirements=requirements, start_date=start_date, end_date=end_date, created_by=current_user.id, ) db.add(mission) db.commit() db.refresh(mission) return {"status": "created", "mission_id": mission.id} @router.get("/missions/{mission_id}") async def get_mission( mission_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Get mission details.""" mission = db.query(Mission).filter(Mission.id == mission_id).first() if not mission: raise HTTPException(status_code=404, detail="Mission not found") return { "id": mission.id, "mission_id": mission.mission_id, "title": mission.title, "description": mission.description, "city": mission.city, "country": mission.country, "location": mission.location, "status": mission.status.value, "reward_amount": float(mission.reward_amount) if mission.reward_amount else None, "reward_currency": mission.reward_currency, "requirements": mission.requirements, "start_date": mission.start_date.isoformat() if mission.start_date else None, "end_date": mission.end_date.isoformat() if mission.end_date else None, } @router.put("/missions/{mission_id}") async def update_mission( mission_id: int, title: Optional[str] = None, status: Optional[MissionStatus] = None, reward_amount: Optional[float] = None, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Update a mission.""" mission = db.query(Mission).filter(Mission.id == mission_id).first() if not mission: raise HTTPException(status_code=404, detail="Mission not found") if title: mission.title = title if status: mission.status = status if reward_amount: mission.reward_amount = reward_amount db.commit() db.refresh(mission) return {"status": "updated", "mission_id": mission.id} # ─── CONTRIBUTORS ───────────────────────────────────────────────────────────── @router.get("/contributors") async def list_contributors( status: Optional[str] = None, city: Optional[str] = None, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """List all contributors.""" query = db.query(Contributor) if status: query = query.filter(Contributor.status == status) if city: query = query.filter(Contributor.city.ilike(f"%{city}%")) contributors = query.offset(skip).limit(limit).all() return { "contributors": [ { "id": c.id, "contributor_id": c.contributor_id, "full_name": c.full_name, "email": c.email, "city": c.city, "country": c.country, "reputation_score": c.reputation_score, "total_earnings": float(c.total_earnings) if c.total_earnings else 0, "total_submissions": c.total_submissions, "verified": c.verified, "status": c.status, } for c in contributors ], "total": query.count(), } @router.post("/contributors") async def create_contributor( contributor_id: str, full_name: str, email: str, city: Optional[str] = None, country: Optional[str] = None, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Register a new contributor.""" contributor = Contributor( contributor_id=contributor_id, full_name=full_name, email=email, city=city, country=country, ) db.add(contributor) db.commit() db.refresh(contributor) return {"status": "created", "contributor_id": contributor.id} @router.get("/contributors/{contributor_id}") async def get_contributor( contributor_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Get contributor details.""" contributor = db.query(Contributor).filter(Contributor.id == contributor_id).first() if not contributor: raise HTTPException(status_code=404, detail="Contributor not found") return { "id": contributor.id, "contributor_id": contributor.contributor_id, "full_name": contributor.full_name, "email": contributor.email, "phone": contributor.phone, "city": contributor.city, "country": contributor.country, "reputation_score": contributor.reputation_score, "total_earnings": float(contributor.total_earnings) if contributor.total_earnings else 0, "total_submissions": contributor.total_submissions, "verified": contributor.verified, "status": contributor.status, } # ─── SUBMISSIONS ────────────────────────────────────────────────────────────── @router.get("/submissions") async def list_submissions( mission_id: Optional[int] = None, status: Optional[str] = None, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """List submissions with filtering.""" query = db.query(Submission) if mission_id: query = query.filter(Submission.mission_id == mission_id) if status: query = query.filter(Submission.status == status) submissions = query.offset(skip).limit(limit).all() return { "submissions": [ { "id": s.id, "submission_id": s.submission_id, "mission_id": s.mission_id, "contributor_id": s.contributor_id, "status": s.status, "ai_score": s.ai_score, "submitted_at": s.submitted_at.isoformat() if s.submitted_at else None, "reviewed_at": s.reviewed_at.isoformat() if s.reviewed_at else None, } for s in submissions ], "total": query.count(), } @router.put("/submissions/{submission_id}/review") async def review_submission( submission_id: int, status: str, # approved, rejected reviewer_notes: Optional[str] = None, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Review a submission.""" submission = db.query(Submission).filter(Submission.id == submission_id).first() if not submission: raise HTTPException(status_code=404, detail="Submission not found") submission.status = status submission.reviewer_notes = reviewer_notes submission.reviewed_at = datetime.utcnow() submission.reviewed_by = current_user.id db.commit() db.refresh(submission) return {"status": "reviewed", "submission_id": submission.id, "new_status": status}