"""Law API endpoints.""" from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import get_db from app.models.law import LawType, LawStatus from app.schemas.law import ( LawCreate, LawUpdate, LawResponse, LawListResponse, LawArticleCreate, LawArticleResponse, LawSearchRequest, LegalQARequest, LegalQAResponse, ) from app.services.law_service import LawService from app.services.llm_service import llm_service router = APIRouter(prefix="/laws", tags=["laws"]) @router.post("", response_model=LawResponse) async def create_law( law_data: LawCreate, db: AsyncSession = Depends(get_db), ): """Create a new law.""" service = LawService(db) law = await service.create_law( title=law_data.title, law_type=LawType(law_data.law_type.value), promulgation_date=law_data.promulgation_date, effective_date=law_data.effective_date, issuing_authority=law_data.issuing_authority, content=law_data.content, status=LawStatus(law_data.status.value), document_number=law_data.document_number, ) return law @router.get("", response_model=LawListResponse) async def list_laws( skip: int = Query(0, ge=0), limit: int = Query(20, ge=1, le=100), law_type: Optional[str] = Query(None), status: Optional[str] = Query(None), db: AsyncSession = Depends(get_db), ): """List laws with optional filters.""" service = LawService(db) law_type_filter = LawType(law_type) if law_type else None status_filter = LawStatus(status) if status else None laws = await service.get_laws_list( skip=skip, limit=limit, law_type=law_type_filter, status=status_filter, ) return LawListResponse( items=laws, total=len(laws), skip=skip, limit=limit, ) @router.get("/{law_id}", response_model=LawResponse) async def get_law( law_id: int, db: AsyncSession = Depends(get_db), ): """Get a law by ID.""" service = LawService(db) law = await service.get_law_by_id(law_id) if not law: raise HTTPException(status_code=404, detail="Law not found") return law @router.put("/{law_id}", response_model=LawResponse) async def update_law( law_id: int, law_data: LawUpdate, db: AsyncSession = Depends(get_db), ): """Update a law.""" service = LawService(db) update_dict = law_data.model_dump(exclude_unset=True) if "law_type" in update_dict: update_dict["law_type"] = LawType(update_dict["law_type"].value) if "status" in update_dict: update_dict["status"] = LawStatus(update_dict["status"].value) law = await service.update_law(law_id, **update_dict) if not law: raise HTTPException(status_code=404, detail="Law not found") return law @router.delete("/{law_id}") async def delete_law( law_id: int, db: AsyncSession = Depends(get_db), ): """Delete a law.""" service = LawService(db) success = await service.delete_law(law_id) if not success: raise HTTPException(status_code=404, detail="Law not found") return {"message": "Law deleted successfully"} @router.post("/search", response_model=LawListResponse) async def search_laws( search_data: LawSearchRequest, db: AsyncSession = Depends(get_db), ): """Search laws by keyword.""" service = LawService(db) laws = await service.search_laws_by_keyword( keyword=search_data.keyword, limit=search_data.limit, ) return LawListResponse( items=laws, total=len(laws), skip=0, limit=search_data.limit, ) @router.post("/qa", response_model=LegalQAResponse) async def legal_qa( qa_data: LegalQARequest, ): """Ask a legal question and get AI-powered answer.""" answer = await llm_service.legal_qa( question=qa_data.question, context=qa_data.context, ) return LegalQAResponse( question=qa_data.question, answer=answer, references=[], ) @router.post("/{law_id}/articles", response_model=LawArticleResponse) async def create_article( law_id: int, article_data: LawArticleCreate, db: AsyncSession = Depends(get_db), ): """Create a law article.""" service = LawService(db) # Verify law exists law = await service.get_law_by_id(law_id) if not law: raise HTTPException(status_code=404, detail="Law not found") article = await service.create_article( law_id=law_id, article_number=article_data.article_number, content=article_data.content, ) return article