Add external calendar profile contract

This commit is contained in:
2026-08-02 05:59:06 +02:00
parent d6255f9f8f
commit ca35aad286
2 changed files with 71 additions and 2 deletions
+67
View File
@@ -9,6 +9,7 @@ from typing import Protocol, runtime_checkable
CAPABILITY_CALENDAR_SCHEDULING = "calendar.scheduling"
CAPABILITY_CALENDAR_OUTBOX = "calendar.outbox"
CAPABILITY_CALENDAR_INVITATIONS = "calendar.invitations"
CAPABILITY_CALENDAR_EXTERNAL_PROFILES = "calendar.externalProfiles"
CALENDAR_AVAILABILITY_READ_SCOPE = "calendar:availability:read"
CALENDAR_EVENT_WRITE_SCOPE = "calendar:event:write"
@@ -90,6 +91,38 @@ class CalendarInvitationRef:
degraded_reasons: tuple[str, ...] = ()
@dataclass(frozen=True, slots=True)
class CalendarExternalProfileRequest:
"""Connector-neutral request for a Calendar-owned external profile."""
profile_kind: str
calendar_id: str
endpoint_url: str
display_name: str | None = None
auth_type: str = "none"
username: str | None = None
credential_ref: str | None = None
sync_enabled: bool = True
sync_interval_seconds: int = 900
sync_direction: str = "two_way"
conflict_policy: str = "etag"
connector_profile_ref: str | None = None
identity_mapping_ref: str | None = None
resource_calendar_ref: str | None = None
metadata: Mapping[str, object] = field(default_factory=dict)
@dataclass(frozen=True, slots=True)
class CalendarExternalProfileRef:
source_id: str
calendar_id: str
profile_kind: str
transport_kind: str
connector_profile_ref: str | None = None
identity_mapping_ref: str | None = None
resource_calendar_ref: str | None = None
@runtime_checkable
class CalendarSchedulingProvider(Protocol):
def list_freebusy(
@@ -165,6 +198,25 @@ class CalendarInvitationProvider(Protocol):
) -> CalendarInvitationRef:
...
@runtime_checkable
class CalendarExternalProfileProvider(Protocol):
"""Optional connector route for Calendar-owned groupware adapters."""
def supported_profiles(self) -> Sequence[Mapping[str, object]]:
...
def configure_profile(
self,
session: object,
*,
tenant_id: str,
user_id: str | None,
request: CalendarExternalProfileRequest,
) -> CalendarExternalProfileRef:
...
def calendar_scheduling_provider(registry: object | None) -> CalendarSchedulingProvider | None:
if registry is None or not hasattr(registry, "has_capability"):
return None
@@ -192,3 +244,18 @@ def calendar_invitation_provider(
return None
capability = registry.capability(CAPABILITY_CALENDAR_INVITATIONS)
return capability if isinstance(capability, CalendarInvitationProvider) else None
def calendar_external_profile_provider(
registry: object | None,
) -> CalendarExternalProfileProvider | None:
if registry is None or not hasattr(registry, "has_capability"):
return None
if not registry.has_capability(CAPABILITY_CALENDAR_EXTERNAL_PROFILES):
return None
capability = registry.capability(CAPABILITY_CALENDAR_EXTERNAL_PROFILES)
return (
capability
if isinstance(capability, CalendarExternalProfileProvider)
else None
)