Compare commits
1 Commits
0eb2deb4ca
...
feature/pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
deb329f4cf |
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,3 +1,11 @@
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*.pyo
|
||||
.Python
|
||||
*.egg-info/
|
||||
.eggs/
|
||||
|
||||
# Binaries
|
||||
/bin/
|
||||
*.exe
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form, Request
|
||||
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form, Request, Query
|
||||
from fastapi.responses import StreamingResponse
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import or_
|
||||
from sqlalchemy import or_, func
|
||||
from typing import List, Optional
|
||||
import math
|
||||
import re
|
||||
|
||||
from .database import get_db
|
||||
@@ -16,6 +17,7 @@ from .schemas import (
|
||||
UploadResponse,
|
||||
ConsumerResponse,
|
||||
HealthResponse,
|
||||
PaginatedResponse, PaginationMeta,
|
||||
)
|
||||
|
||||
router = APIRouter()
|
||||
@@ -39,13 +41,44 @@ def health_check():
|
||||
|
||||
|
||||
# Project routes
|
||||
@router.get("/api/v1/projects", response_model=List[ProjectResponse])
|
||||
def list_projects(request: Request, db: Session = Depends(get_db)):
|
||||
@router.get("/api/v1/projects", response_model=PaginatedResponse[ProjectResponse])
|
||||
def list_projects(
|
||||
request: Request,
|
||||
page: int = Query(default=1, ge=1, description="Page number"),
|
||||
limit: int = Query(default=20, ge=1, le=100, description="Items per page"),
|
||||
search: Optional[str] = Query(default=None, description="Search by project name"),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
user_id = get_user_id(request)
|
||||
projects = db.query(Project).filter(
|
||||
|
||||
# Base query - filter by access
|
||||
query = db.query(Project).filter(
|
||||
or_(Project.is_public == True, Project.created_by == user_id)
|
||||
).order_by(Project.name).all()
|
||||
return projects
|
||||
)
|
||||
|
||||
# Apply search filter (case-insensitive)
|
||||
if search:
|
||||
query = query.filter(func.lower(Project.name).contains(search.lower()))
|
||||
|
||||
# Get total count before pagination
|
||||
total = query.count()
|
||||
|
||||
# Apply pagination
|
||||
offset = (page - 1) * limit
|
||||
projects = query.order_by(Project.name).offset(offset).limit(limit).all()
|
||||
|
||||
# Calculate total pages
|
||||
total_pages = math.ceil(total / limit) if total > 0 else 1
|
||||
|
||||
return PaginatedResponse(
|
||||
items=projects,
|
||||
pagination=PaginationMeta(
|
||||
page=page,
|
||||
limit=limit,
|
||||
total=total,
|
||||
total_pages=total_pages,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@router.post("/api/v1/projects", response_model=ProjectResponse)
|
||||
|
||||
@@ -1,8 +1,23 @@
|
||||
from datetime import datetime
|
||||
from typing import Optional, List
|
||||
from typing import Optional, List, Generic, TypeVar
|
||||
from pydantic import BaseModel
|
||||
from uuid import UUID
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
# Pagination schemas
|
||||
class PaginationMeta(BaseModel):
|
||||
page: int
|
||||
limit: int
|
||||
total: int
|
||||
total_pages: int
|
||||
|
||||
|
||||
class PaginatedResponse(BaseModel, Generic[T]):
|
||||
items: List[T]
|
||||
pagination: PaginationMeta
|
||||
|
||||
|
||||
# Project schemas
|
||||
class ProjectCreate(BaseModel):
|
||||
|
||||
Reference in New Issue
Block a user