Add admin-frontend and user-frontend standalone projects, certification/invoice/discovery features, fix auth header and theme consistency

This commit is contained in:
TradeMate Dev
2026-05-22 18:35:30 +08:00
parent 18c6cf5406
commit 52dba37f22
79 changed files with 10333 additions and 248 deletions
+62
View File
@@ -6,6 +6,8 @@ from sqlalchemy.ext.asyncio import AsyncSession
from app.database import get_db
from app.services.admin import AdminService
from app.services.translation_quota import TranslationQuotaService
from app.services.certification import CertificationService
from app.services.invoice import InvoiceService
from app.api.v1.deps import get_current_user
router = APIRouter()
@@ -212,3 +214,63 @@ async def reset_translation_quota(
if not result:
raise HTTPException(status_code=404, detail="Quota not found")
return result
@router.get("/certifications")
async def admin_list_certifications(
page: int = Query(1, ge=1),
size: int = Query(20, ge=1, le=100),
status: Optional[str] = Query(None),
_: dict = Depends(require_admin),
db: AsyncSession = Depends(get_db),
):
service = CertificationService(db)
return await service.list_all(page, size, status)
@router.post("/certifications/{cert_id}/review")
async def admin_review_certification(
cert_id: str,
data: dict,
_: dict = Depends(require_admin),
db: AsyncSession = Depends(get_db),
):
_validate_uuid(cert_id)
service = CertificationService(db)
action = data.get("action")
if action not in ("approve", "reject"):
raise HTTPException(status_code=400, detail="Action must be 'approve' or 'reject'")
result = await service.review(cert_id, action, data.get("reason"))
if not result:
raise HTTPException(status_code=404, detail="Certification not found")
return result
@router.get("/invoices")
async def admin_list_invoices(
page: int = Query(1, ge=1),
size: int = Query(20, ge=1, le=100),
status: Optional[str] = Query(None),
_: dict = Depends(require_admin),
db: AsyncSession = Depends(get_db),
):
service = InvoiceService(db)
return await service.list_all(page, size, status)
@router.post("/invoices/{invoice_id}/process")
async def admin_process_invoice(
invoice_id: str,
data: dict,
_: dict = Depends(require_admin),
db: AsyncSession = Depends(get_db),
):
_validate_uuid(invoice_id)
service = InvoiceService(db)
action = data.get("action")
if action not in ("issue", "reject"):
raise HTTPException(status_code=400, detail="Action must be 'issue' or 'reject'")
result = await service.process(invoice_id, action, data.get("reason"))
if not result:
raise HTTPException(status_code=404, detail="Invoice not found")
return result