MCPcopy
hub / github.com/learnhouse/learnhouse / bulk_enroll_users

Function bulk_enroll_users

apps/api/src/services/admin/admin.py:1358–1467  ·  view source on GitHub ↗

Enroll a batch of users in a course. Returns summary of results.

(
    token_user: APITokenUser,
    course_uuid: str,
    user_ids: List[int],
    request: Request,
    db_session: AsyncSession,
)

Source from the content-addressed store, hash-verified

1356
1357
1358async def bulk_enroll_users(
1359 token_user: APITokenUser,
1360 course_uuid: str,
1361 user_ids: List[int],
1362 request: Request,
1363 db_session: AsyncSession,
1364) -> dict:
1365 """Enroll a batch of users in a course. Returns summary of results."""
1366
1367 course = (await db_session.execute(
1368 select(Course).where(
1369 Course.course_uuid == course_uuid,
1370 Course.org_id == token_user.org_id,
1371 )
1372 )).scalars().first()
1373 if not course:
1374 raise HTTPException(status_code=404, detail="Course not found")
1375
1376 # Pre-fetch memberships, existing enrollments, and trails in 3 queries total
1377 member_ids = set(
1378 (await db_session.execute(
1379 select(UserOrganization.user_id).where(
1380 UserOrganization.user_id.in_(user_ids),
1381 UserOrganization.org_id == token_user.org_id,
1382 )
1383 )).scalars().all()
1384 )
1385 already_enrolled_ids = set(
1386 (await db_session.execute(
1387 select(TrailRun.user_id).where(
1388 TrailRun.course_id == course.id,
1389 TrailRun.user_id.in_(user_ids),
1390 TrailRun.org_id == token_user.org_id,
1391 )
1392 )).scalars().all()
1393 )
1394
1395 enrolled: List[int] = []
1396 already_enrolled: List[int] = []
1397 skipped: List[int] = []
1398 to_enroll: List[int] = []
1399
1400 for user_id in user_ids:
1401 if user_id not in member_ids:
1402 skipped.append(user_id)
1403 elif user_id in already_enrolled_ids:
1404 already_enrolled.append(user_id)
1405 else:
1406 to_enroll.append(user_id)
1407
1408 if not to_enroll:
1409 return {"enrolled": enrolled, "already_enrolled": already_enrolled, "skipped": skipped}
1410
1411 now = datetime.now()
1412 trails_by_user: dict[int, Trail] = {
1413 t.user_id: t
1414 for t in (await db_session.execute(
1415 select(Trail).where(

Callers 12

test_enrolls_membersMethod · 0.90
test_course_not_foundMethod · 0.90
test_mixed_resultsMethod · 0.90
test_paginationMethod · 0.90
test_deletes_stepsMethod · 0.90
test_unenrolls_usersMethod · 0.90
test_with_enrollmentsMethod · 0.90
api_admin_bulk_enrollFunction · 0.90

Calls 9

TrailClass · 0.90
TrailRunClass · 0.90
trackFunction · 0.90
flushMethod · 0.80
commitMethod · 0.80
firstMethod · 0.45
scalarsMethod · 0.45
executeMethod · 0.45
allMethod · 0.45

Tested by 11

test_enrolls_membersMethod · 0.72
test_course_not_foundMethod · 0.72
test_mixed_resultsMethod · 0.72
test_paginationMethod · 0.72
test_deletes_stepsMethod · 0.72
test_unenrolls_usersMethod · 0.72
test_with_enrollmentsMethod · 0.72