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)