Add scheduling calendar integration and WebUI
This commit is contained in:
@@ -8,7 +8,11 @@ from govoplan_core.db.session import get_session
|
||||
from govoplan_poll.backend.schemas import PollResultSummaryResponse
|
||||
from govoplan_scheduling.backend.manifest import READ_SCOPE, WRITE_SCOPE
|
||||
from govoplan_scheduling.backend.schemas import (
|
||||
SchedulingCalendarActionResponse,
|
||||
SchedulingDecisionRequest,
|
||||
SchedulingNotificationCreateRequest,
|
||||
SchedulingNotificationListResponse,
|
||||
SchedulingNotificationResponse,
|
||||
SchedulingRequestCreateRequest,
|
||||
SchedulingRequestListResponse,
|
||||
SchedulingRequestResponse,
|
||||
@@ -20,11 +24,17 @@ from govoplan_scheduling.backend.service import (
|
||||
SchedulingError,
|
||||
cancel_scheduling_request,
|
||||
close_scheduling_request,
|
||||
create_final_calendar_event,
|
||||
create_scheduling_notification_jobs,
|
||||
create_scheduling_request,
|
||||
create_tentative_calendar_holds,
|
||||
decide_scheduling_request,
|
||||
evaluate_calendar_freebusy,
|
||||
get_scheduling_request,
|
||||
list_scheduling_notifications,
|
||||
list_scheduling_requests,
|
||||
open_scheduling_request,
|
||||
scheduling_notification_response,
|
||||
scheduling_request_response,
|
||||
scheduling_request_summary,
|
||||
update_scheduling_request,
|
||||
@@ -147,12 +157,83 @@ def api_decide_scheduling_request(
|
||||
) -> SchedulingStatusResponse:
|
||||
_require_scope(principal, WRITE_SCOPE)
|
||||
try:
|
||||
request = decide_scheduling_request(session, tenant_id=principal.tenant_id, request_id=request_id, payload=payload)
|
||||
request = decide_scheduling_request(
|
||||
session,
|
||||
tenant_id=principal.tenant_id,
|
||||
request_id=request_id,
|
||||
payload=payload,
|
||||
user_id=principal.account_id,
|
||||
)
|
||||
except SchedulingError as exc:
|
||||
raise _scheduling_http_error(exc) from exc
|
||||
return SchedulingStatusResponse(request=_request_response(request))
|
||||
|
||||
|
||||
@router.post("/requests/{request_id}/calendar/freebusy", response_model=SchedulingCalendarActionResponse)
|
||||
def api_evaluate_calendar_freebusy(
|
||||
request_id: str,
|
||||
session: Session = Depends(get_session),
|
||||
principal: ApiPrincipal = Depends(get_api_principal),
|
||||
) -> SchedulingCalendarActionResponse:
|
||||
_require_scope(principal, WRITE_SCOPE)
|
||||
try:
|
||||
request, warnings = evaluate_calendar_freebusy(session, tenant_id=principal.tenant_id, request_id=request_id)
|
||||
except SchedulingError as exc:
|
||||
raise _scheduling_http_error(exc) from exc
|
||||
return SchedulingCalendarActionResponse(
|
||||
request=_request_response(request),
|
||||
updated_slot_ids=[slot.id for slot in request.slots if slot.freebusy_checked_at is not None],
|
||||
warnings=warnings,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/requests/{request_id}/calendar/holds", response_model=SchedulingCalendarActionResponse)
|
||||
def api_create_tentative_calendar_holds(
|
||||
request_id: str,
|
||||
session: Session = Depends(get_session),
|
||||
principal: ApiPrincipal = Depends(get_api_principal),
|
||||
) -> SchedulingCalendarActionResponse:
|
||||
_require_scope(principal, WRITE_SCOPE)
|
||||
try:
|
||||
request, created_event_ids, warnings = create_tentative_calendar_holds(
|
||||
session,
|
||||
tenant_id=principal.tenant_id,
|
||||
user_id=principal.account_id,
|
||||
request_id=request_id,
|
||||
)
|
||||
except SchedulingError as exc:
|
||||
raise _scheduling_http_error(exc) from exc
|
||||
return SchedulingCalendarActionResponse(
|
||||
request=_request_response(request),
|
||||
created_event_ids=created_event_ids,
|
||||
updated_slot_ids=[slot.id for slot in request.slots if slot.tentative_hold_event_id in created_event_ids],
|
||||
warnings=warnings,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/requests/{request_id}/calendar/event", response_model=SchedulingCalendarActionResponse)
|
||||
def api_create_final_calendar_event(
|
||||
request_id: str,
|
||||
session: Session = Depends(get_session),
|
||||
principal: ApiPrincipal = Depends(get_api_principal),
|
||||
) -> SchedulingCalendarActionResponse:
|
||||
_require_scope(principal, WRITE_SCOPE)
|
||||
try:
|
||||
request, event_id, warnings = create_final_calendar_event(
|
||||
session,
|
||||
tenant_id=principal.tenant_id,
|
||||
user_id=principal.account_id,
|
||||
request_id=request_id,
|
||||
)
|
||||
except SchedulingError as exc:
|
||||
raise _scheduling_http_error(exc) from exc
|
||||
return SchedulingCalendarActionResponse(
|
||||
request=_request_response(request),
|
||||
created_event_ids=[event_id] if event_id else [],
|
||||
warnings=warnings,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/requests/{request_id}/cancel", response_model=SchedulingStatusResponse)
|
||||
def api_cancel_scheduling_request(
|
||||
request_id: str,
|
||||
@@ -183,3 +264,52 @@ def api_scheduling_summary(
|
||||
request=_request_response(request),
|
||||
poll_summary=PollResultSummaryResponse.model_validate(summary),
|
||||
)
|
||||
|
||||
|
||||
@router.get("/notifications", response_model=SchedulingNotificationListResponse)
|
||||
def api_list_scheduling_notifications(
|
||||
request_id: str | None = None,
|
||||
status_filter: str | None = Query(default=None, alias="status"),
|
||||
session: Session = Depends(get_session),
|
||||
principal: ApiPrincipal = Depends(get_api_principal),
|
||||
) -> SchedulingNotificationListResponse:
|
||||
_require_scope(principal, READ_SCOPE)
|
||||
notifications = list_scheduling_notifications(
|
||||
session,
|
||||
tenant_id=principal.tenant_id,
|
||||
request_id=request_id,
|
||||
status=status_filter,
|
||||
)
|
||||
return SchedulingNotificationListResponse(
|
||||
notifications=[
|
||||
SchedulingNotificationResponse.model_validate(scheduling_notification_response(notification))
|
||||
for notification in notifications
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@router.post("/requests/{request_id}/notifications", response_model=SchedulingNotificationListResponse)
|
||||
def api_create_scheduling_notifications(
|
||||
request_id: str,
|
||||
payload: SchedulingNotificationCreateRequest,
|
||||
session: Session = Depends(get_session),
|
||||
principal: ApiPrincipal = Depends(get_api_principal),
|
||||
) -> SchedulingNotificationListResponse:
|
||||
_require_scope(principal, WRITE_SCOPE)
|
||||
try:
|
||||
notifications = create_scheduling_notification_jobs(
|
||||
session,
|
||||
tenant_id=principal.tenant_id,
|
||||
request_id=request_id,
|
||||
event_kind=payload.event_kind,
|
||||
channel=payload.channel,
|
||||
metadata=payload.metadata,
|
||||
)
|
||||
except SchedulingError as exc:
|
||||
raise _scheduling_http_error(exc) from exc
|
||||
return SchedulingNotificationListResponse(
|
||||
notifications=[
|
||||
SchedulingNotificationResponse.model_validate(scheduling_notification_response(notification))
|
||||
for notification in notifications
|
||||
]
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user