feat: deploy infrastructure + disk/drive, calendar, presentation, workspaces, onboarding, demo user

This commit is contained in:
2026-05-19 16:26:26 +03:00
parent 688d043dad
commit 3529c39b22
304 changed files with 18826 additions and 1176 deletions
+35
View File
@@ -0,0 +1,35 @@
"""Apple CalDAV stub implementation.
When credentials are empty, logs the operation and returns True.
Real CalDAV implementation deferred.
"""
import logging
logger = logging.getLogger(__name__)
class AppleCalDavStub:
"""Apple Calendar via CalDAV (stub — logs only)."""
async def create_event(
self,
summary: str,
description: str,
start_iso: str,
end_iso: str,
**kwargs,
) -> bool:
logger.info(
"Apple CalDAV stub: create_event called — "
"summary=%s, start=%s, end=%s",
summary, start_iso, end_iso,
)
return True
async def list_events(self, max_results: int = 10) -> list[dict]:
logger.info("Apple CalDAV stub: list_events called")
return []
async def health_check(self) -> bool:
return True
@@ -0,0 +1,58 @@
"""Google Calendar API client for VoIdea.
Uses OAuth access token to create events via Google Calendar API v3.
"""
import logging
import httpx
logger = logging.getLogger(__name__)
GOOGLE_CALENDAR_URL = "https://www.googleapis.com/calendar/v3"
class GoogleCalendarClient:
def __init__(self, access_token: str):
self._access_token = access_token
async def create_event(
self,
summary: str,
description: str,
start_iso: str,
end_iso: str,
**kwargs,
) -> bool:
async with httpx.AsyncClient() as client:
resp = await client.post(
f"{GOOGLE_CALENDAR_URL}/calendars/primary/events",
headers={
"Authorization": f"Bearer {self._access_token}",
"Content-Type": "application/json",
},
json={
"summary": summary,
"description": description,
"start": {"dateTime": start_iso, "timeZone": "UTC"},
"end": {"dateTime": end_iso, "timeZone": "UTC"},
},
)
if resp.status_code == 200:
return True
logger.error("Google Calendar create_event failed: %s %s", resp.status_code, resp.text)
return False
async def list_events(self, max_results: int = 10) -> list[dict]:
async with httpx.AsyncClient() as client:
resp = await client.get(
f"{GOOGLE_CALENDAR_URL}/calendars/primary/events",
headers={"Authorization": f"Bearer {self._access_token}"},
params={"maxResults": max_results, "orderBy": "startTime", "singleEvents": "true"},
)
if resp.status_code == 200:
return resp.json().get("items", [])
return []
async def health_check(self) -> bool:
return bool(self._access_token)
@@ -0,0 +1,58 @@
"""Yandex Calendar API client for VoIdea.
Uses OAuth access token to create events via Yandex Calendar API.
"""
import logging
import httpx
logger = logging.getLogger(__name__)
YANDEX_CALENDAR_URL = "https://calendar.yandex.ru/api"
class YandexCalendarClient:
def __init__(self, access_token: str):
self._access_token = access_token
async def create_event(
self,
summary: str,
description: str,
start_iso: str,
end_iso: str,
**kwargs,
) -> bool:
async with httpx.AsyncClient() as client:
resp = await client.post(
f"{YANDEX_CALENDAR_URL}/events",
headers={
"Authorization": f"OAuth {self._access_token}",
"Content-Type": "application/json",
},
json={
"summary": summary,
"description": description,
"start": {"dateTime": start_iso, "timeZone": "UTC"},
"end": {"dateTime": end_iso, "timeZone": "UTC"},
},
)
if resp.status_code in (200, 201):
return True
logger.error("Yandex Calendar create_event failed: %s %s", resp.status_code, resp.text)
return False
async def list_events(self, max_results: int = 10) -> list[dict]:
async with httpx.AsyncClient() as client:
resp = await client.get(
f"{YANDEX_CALENDAR_URL}/events",
headers={"Authorization": f"OAuth {self._access_token}"},
params={"maxResults": max_results},
)
if resp.status_code == 200:
return resp.json().get("events", [])
return []
async def health_check(self) -> bool:
return bool(self._access_token)