api endpoints fix and inclusion
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2025-08-10 15:39:48 +09:00
parent 7ecc556c77
commit b595bcc9bc
65 changed files with 6046 additions and 263 deletions

View File

@@ -7,6 +7,8 @@ WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --upgrade pip \
&& pip install --no-cache-dir -r requirements.txt
RUN mkdir -p /app/uploads
COPY src ./src
COPY alembic.ini ./

View File

@@ -0,0 +1,6 @@
#!/usr/bin/env sh
set -e
# Run migrations (no-op if no revisions yet)
alembic -c alembic.ini upgrade head || true
# Start app
exec uvicorn app.main:app --host 0.0.0.0 --port 8000

View File

@@ -0,0 +1,26 @@
from typing import Optional, List
from fastapi import APIRouter, Depends, Query, HTTPException
from sqlalchemy.orm import Session
from ...db.session import get_db
from ...core.security import require_roles, UserClaims
from ...schemas.user import UserRead
from ...repositories.user_search_repository import UserSearchRepository
router = APIRouter(prefix="/v1/users", tags=["users"])
@router.get("/search", response_model=List[UserRead])
def search_users(q: Optional[str] = None,
role: Optional[str] = Query(None, pattern="^(ADMIN|CLIENT)$"),
is_active: Optional[bool] = None,
email_domain: Optional[str] = None,
created_from: Optional[str] = None,
created_to: Optional[str] = None,
sort_by: Optional[str] = Query(None, pattern="^(full_name|email|created_at|role|is_active)$"),
order: Optional[str] = Query("asc", pattern="^(asc|desc)$"),
offset: int = 0, limit: int = Query(50, le=200),
db: Session = Depends(get_db),
_: UserClaims = Depends(require_roles("ADMIN"))):
repo = UserSearchRepository(db)
return repo.search(q=q, role=role, is_active=is_active, email_domain=email_domain,
created_from=created_from, created_to=created_to,
sort_by=sort_by, order=order, offset=offset, limit=limit)

View File

@@ -0,0 +1,14 @@
from fastapi import FastAPI
from .api.routes.ping import router as ping_router
from .api.routes.auth import router as auth_router
from .api.routes.users import router as users_router
app = FastAPI(title="AUTH Service")
@app.get("/health")
def health():
return {"status": "ok", "service": "auth"}
app.include_router(ping_router, prefix="/v1")
app.include_router(auth_router)
app.include_router(users_router)

View File

@@ -0,0 +1,38 @@
from typing import List, Optional
from sqlalchemy.orm import Session
from sqlalchemy import or_, func
from ..models.user import User
class UserSearchRepository:
def __init__(self, db: Session):
self.db = db
def search(self, q: Optional[str], role: Optional[str], is_active: Optional[bool],
email_domain: Optional[str], created_from: Optional[str], created_to: Optional[str],
sort_by: Optional[str], order: Optional[str], offset: int, limit: int) -> List[User]:
qry = self.db.query(User)
if q:
like = f"%{q}%"
qry = qry.filter(or_(User.email.ilike(like), User.full_name.ilike(like)))
if role:
qry = qry.filter(User.role == role)
if is_active is not None:
qry = qry.filter(User.is_active == is_active)
if email_domain:
qry = qry.filter(User.email.ilike(f"%@{email_domain}"))
if created_from:
qry = qry.filter(User.created_at >= created_from)
if created_to:
qry = qry.filter(User.created_at <= created_to)
sort_map = {
"full_name": User.full_name,
"email": User.email,
"created_at": User.created_at,
"role": User.role,
"is_active": User.is_active
}
col = sort_map.get(sort_by or "", User.created_at)
if order == "desc":
col = col.desc()
return qry.order_by(col).offset(offset).limit(min(limit, 200)).all()