feat(scheduling): enforce participant roster privacy

This commit is contained in:
2026-07-20 18:44:28 +02:00
parent d0b95eee58
commit 6141f39bf8
9 changed files with 430 additions and 4 deletions

View File

@@ -12,6 +12,7 @@ SchedulingParticipantType = Literal["internal", "external", "resource"]
SchedulingParticipantStatus = Literal["draft", "invited", "responded", "declined", "removed"]
SchedulingResultVisibility = Literal["organizer", "after_response", "after_close", "public"]
SchedulingAvailabilityValue = Literal["available", "maybe", "unavailable"]
SchedulingParticipantVisibility = Literal["aggregates_only", "names_and_statuses"]
def _known_timezone(value: str | None) -> str | None:
@@ -103,6 +104,7 @@ class SchedulingRequestCreateRequest(BaseModel):
allow_external_participants: bool = True
allow_participant_updates: bool = True
result_visibility: SchedulingResultVisibility = "after_close"
participant_visibility: SchedulingParticipantVisibility = "aggregates_only"
calendar: SchedulingCalendarPreferences = Field(default_factory=SchedulingCalendarPreferences)
slots: list[SchedulingCandidateSlotInput] = Field(default_factory=list, min_length=1)
participants: list[SchedulingParticipantInput] = Field(default_factory=list)
@@ -122,6 +124,7 @@ class SchedulingRequestUpdateRequest(BaseModel):
allow_external_participants: bool | None = None
allow_participant_updates: bool | None = None
result_visibility: SchedulingResultVisibility | None = None
participant_visibility: SchedulingParticipantVisibility | None = None
calendar: SchedulingCalendarPreferences | None = None
metadata: dict[str, Any] | None = None
@@ -159,6 +162,20 @@ class SchedulingParticipantResponse(BaseModel):
metadata: dict[str, Any] = Field(default_factory=dict)
class SchedulingParticipantAggregateResponse(BaseModel):
total: int = 0
status_counts: dict[str, int] = Field(default_factory=dict)
class SchedulingParticipantVisibilityDecisionResponse(BaseModel):
requested_visibility: SchedulingParticipantVisibility
effective_visibility: SchedulingParticipantVisibility
policy_applied: bool = False
reason: str | None = None
source_path: list[dict[str, Any]] = Field(default_factory=list)
details: dict[str, Any] = Field(default_factory=dict)
class SchedulingRequestResponse(BaseModel):
id: str
tenant_id: str
@@ -174,6 +191,10 @@ class SchedulingRequestResponse(BaseModel):
allow_external_participants: bool
allow_participant_updates: bool
result_visibility: str
participant_visibility: SchedulingParticipantVisibility
effective_participant_visibility: SchedulingParticipantVisibility
participant_aggregate: SchedulingParticipantAggregateResponse
participant_visibility_decision: SchedulingParticipantVisibilityDecisionResponse
calendar_integration_enabled: bool
calendar_id: str | None = None
calendar_freebusy_enabled: bool