67 lines
2.4 KiB
Python
67 lines
2.4 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.core.deps import ensure_class_access, get_current_user, resolve_class_id_for_user
|
|
from app.db.database import get_db
|
|
from app.db.models import User
|
|
from app.schemas.user import UserPublic
|
|
from app.schemas.common import PageResponse
|
|
from app.services.directory_service import search_directory, user_to_public
|
|
from app.services.user_service import get_user_by_id
|
|
|
|
router = APIRouter(prefix="/api/directory", tags=["directory"])
|
|
|
|
|
|
@router.get("/", response_model=PageResponse[UserPublic])
|
|
async def search_members(
|
|
search: str | None = None,
|
|
industry: str | None = None,
|
|
company: str | None = None,
|
|
class_id: int | None = None,
|
|
page: int = 1,
|
|
page_size: int = 20,
|
|
user: User = Depends(get_current_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
effective_class_id = resolve_class_id_for_user(user, class_id)
|
|
if effective_class_id is None:
|
|
return PageResponse(items=[], total=0, page=page, page_size=page_size, total_pages=0)
|
|
ensure_class_access(user, effective_class_id)
|
|
|
|
users, total = await search_directory(
|
|
db, effective_class_id, search, industry, company, page, page_size
|
|
)
|
|
total_pages = (total + page_size - 1) // page_size
|
|
include_contact = True # Same class, active members can see contact
|
|
return PageResponse(
|
|
items=[
|
|
user_to_public(u, effective_class_id, include_contact=include_contact)
|
|
for u in users
|
|
],
|
|
total=total,
|
|
page=page,
|
|
page_size=page_size,
|
|
total_pages=total_pages,
|
|
)
|
|
|
|
|
|
@router.get("/{user_id}", response_model=UserPublic)
|
|
async def get_member_detail(
|
|
user_id: int,
|
|
user: User = Depends(get_current_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
target = await get_user_by_id(db, user_id)
|
|
if target is None or target.status != "approved":
|
|
raise HTTPException(status_code=404, detail="User not found")
|
|
|
|
# Privacy: only show contact info to same-class members
|
|
shared_class_ids = {
|
|
membership.class_id for membership in user.memberships
|
|
} & {
|
|
membership.class_id for membership in target.memberships
|
|
}
|
|
include_contact = bool(shared_class_ids)
|
|
scoped_class_id = next(iter(shared_class_ids), None)
|
|
return user_to_public(target, scoped_class_id, include_contact=include_contact)
|