|
@@ -9,14 +9,14 @@ from app.api.utils import ( # adjust import path if different
|
|
|
assert_project_exists_or_404,
|
|
assert_project_exists_or_404,
|
|
|
verify_id_list,
|
|
verify_id_list,
|
|
|
)
|
|
)
|
|
|
-from app.models import OrgRole, Slot, Sms, User, Volunteer, VolunteerGroup
|
|
|
|
|
|
|
+from app.models import OrgRole, Sms, User, Volunteer, VolunteerGroup
|
|
|
from app.schemas.requests import (
|
|
from app.schemas.requests import (
|
|
|
GroupMembershipRequest,
|
|
GroupMembershipRequest,
|
|
|
GroupSmsRequest,
|
|
GroupSmsRequest,
|
|
|
VolunteerGroupCreateRequest,
|
|
VolunteerGroupCreateRequest,
|
|
|
VolunteerGroupUpdateRequest,
|
|
VolunteerGroupUpdateRequest,
|
|
|
)
|
|
)
|
|
|
-from app.schemas.responses import SMSResponse, VolunteerGroupResponse, VolunteerResponse
|
|
|
|
|
|
|
+from app.schemas.responses import SMSResponse, VolunteerGroupResponse
|
|
|
|
|
|
|
|
router = APIRouter(prefix="/project/{project_id}", tags=["volunteer_groups"])
|
|
router = APIRouter(prefix="/project/{project_id}", tags=["volunteer_groups"])
|
|
|
|
|
|
|
@@ -42,7 +42,11 @@ async def list_project_groups(
|
|
|
return results.scalars().all()
|
|
return results.scalars().all()
|
|
|
|
|
|
|
|
|
|
|
|
|
-@router.post("/group", response_model=VolunteerGroupResponse)
|
|
|
|
|
|
|
+@router.post(
|
|
|
|
|
+ "/group",
|
|
|
|
|
+ response_model=VolunteerGroupResponse,
|
|
|
|
|
+ openapi_extra={"sse_event": "volunteer_group_created"},
|
|
|
|
|
+)
|
|
|
async def create_group(
|
|
async def create_group(
|
|
|
project_id: UUID,
|
|
project_id: UUID,
|
|
|
new_group: VolunteerGroupCreateRequest,
|
|
new_group: VolunteerGroupCreateRequest,
|
|
@@ -58,7 +62,10 @@ async def create_group(
|
|
|
return group
|
|
return group
|
|
|
|
|
|
|
|
|
|
|
|
|
-@router.get("/group/{group_id}", response_model=VolunteerGroupResponse)
|
|
|
|
|
|
|
+@router.get(
|
|
|
|
|
+ "/group/{group_id}",
|
|
|
|
|
+ response_model=VolunteerGroupResponse,
|
|
|
|
|
+)
|
|
|
async def get_group(
|
|
async def get_group(
|
|
|
project_id: UUID,
|
|
project_id: UUID,
|
|
|
group_id: UUID,
|
|
group_id: UUID,
|
|
@@ -69,7 +76,11 @@ async def get_group(
|
|
|
return _get_group_or_404(session, project_id, group_id)
|
|
return _get_group_or_404(session, project_id, group_id)
|
|
|
|
|
|
|
|
|
|
|
|
|
-@router.post("/group/{group_id}", response_model=VolunteerGroupResponse)
|
|
|
|
|
|
|
+@router.post(
|
|
|
|
|
+ "/group/{group_id}",
|
|
|
|
|
+ response_model=VolunteerGroupResponse,
|
|
|
|
|
+ openapi_extra={"sse_event": "volunteer_group_updated"},
|
|
|
|
|
+)
|
|
|
async def update_group(
|
|
async def update_group(
|
|
|
project_id: UUID,
|
|
project_id: UUID,
|
|
|
group_id: UUID,
|
|
group_id: UUID,
|
|
@@ -86,7 +97,10 @@ async def update_group(
|
|
|
return group
|
|
return group
|
|
|
|
|
|
|
|
|
|
|
|
|
-@router.delete("/group/{group_id}")
|
|
|
|
|
|
|
+@router.delete(
|
|
|
|
|
+ "/group/{group_id}",
|
|
|
|
|
+ openapi_extra={"sse_event": "volunteer_group_deleted"},
|
|
|
|
|
+)
|
|
|
async def delete_group(
|
|
async def delete_group(
|
|
|
project_id: UUID,
|
|
project_id: UUID,
|
|
|
group_id: UUID,
|
|
group_id: UUID,
|
|
@@ -99,7 +113,11 @@ async def delete_group(
|
|
|
session.commit()
|
|
session.commit()
|
|
|
|
|
|
|
|
|
|
|
|
|
-@router.post("/group/{group_id}/volunteers", response_model=VolunteerGroupResponse)
|
|
|
|
|
|
|
+@router.post(
|
|
|
|
|
+ "/group/{group_id}/volunteers",
|
|
|
|
|
+ response_model=VolunteerGroupResponse,
|
|
|
|
|
+ openapi_extra={"sse_event": "volunteer_group_updated"},
|
|
|
|
|
+)
|
|
|
async def add_volunteers_to_group(
|
|
async def add_volunteers_to_group(
|
|
|
project_id: UUID,
|
|
project_id: UUID,
|
|
|
group_id: UUID,
|
|
group_id: UUID,
|
|
@@ -126,7 +144,11 @@ async def add_volunteers_to_group(
|
|
|
return group
|
|
return group
|
|
|
|
|
|
|
|
|
|
|
|
|
-@router.delete("/group/{group_id}/volunteer/{volunteer_id}", response_model=VolunteerGroupResponse)
|
|
|
|
|
|
|
+@router.delete(
|
|
|
|
|
+ "/group/{group_id}/volunteer/{volunteer_id}",
|
|
|
|
|
+ response_model=VolunteerGroupResponse,
|
|
|
|
|
+ openapi_extra={"sse_event": "volunteer_group_updated"},
|
|
|
|
|
+)
|
|
|
async def remove_volunteer_from_group(
|
|
async def remove_volunteer_from_group(
|
|
|
project_id: UUID,
|
|
project_id: UUID,
|
|
|
group_id: UUID,
|
|
group_id: UUID,
|
|
@@ -144,33 +166,6 @@ async def remove_volunteer_from_group(
|
|
|
return group
|
|
return group
|
|
|
|
|
|
|
|
|
|
|
|
|
-@router.post("/group/{group_id}/add-to-slot/{slot_id}", response_model=list[VolunteerResponse])
|
|
|
|
|
-async def add_group_to_slot(
|
|
|
|
|
- project_id: UUID,
|
|
|
|
|
- group_id: UUID,
|
|
|
|
|
- slot_id: UUID,
|
|
|
|
|
- current_user: User = Depends(deps.require_org_role(*MANAGE_GROUPS)),
|
|
|
|
|
- session: Session = Depends(deps.get_session),
|
|
|
|
|
-):
|
|
|
|
|
- """Bulk-assigns every member of the group to the slot in one call.
|
|
|
|
|
- This is a one-time copy, not a live link: adding someone to the group
|
|
|
|
|
- later does NOT retroactively add them to slots already assigned."""
|
|
|
|
|
- group = _get_group_or_404(session, project_id, group_id)
|
|
|
|
|
-
|
|
|
|
|
- slot = session.get(Slot, slot_id)
|
|
|
|
|
- if slot is None or slot.project_id != str(project_id):
|
|
|
|
|
- raise HTTPException(status_code=404, detail="Slot not found in this project")
|
|
|
|
|
-
|
|
|
|
|
- existing_ids = {v.id for v in slot.volunteers}
|
|
|
|
|
- for volunteer in group.volunteers:
|
|
|
|
|
- if volunteer.id not in existing_ids:
|
|
|
|
|
- slot.volunteers.append(volunteer)
|
|
|
|
|
-
|
|
|
|
|
- session.commit()
|
|
|
|
|
- session.refresh(slot)
|
|
|
|
|
- return slot.volunteers
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
@router.post("/group/{group_id}/send-sms", response_model=list[SMSResponse])
|
|
@router.post("/group/{group_id}/send-sms", response_model=list[SMSResponse])
|
|
|
async def send_sms_to_group(
|
|
async def send_sms_to_group(
|
|
|
project_id: UUID,
|
|
project_id: UUID,
|