| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- """Schemas for Orca Cloud auth + profile sync endpoints."""
- from typing import Literal
- from pydantic import BaseModel, Field
- # The three OAuth providers Orca's sign-in surface offers. Supabase
- # accepts the bare lowercase provider name in the authorize query string.
- OrcaOAuthProvider = Literal["google", "apple", "github"]
- class OrcaAuthStartRequest(BaseModel):
- """Body for ``POST /orca-cloud/auth/start``. Provider defaults to
- ``google`` so existing clients that send an empty body keep working."""
- provider: OrcaOAuthProvider = Field(default="google", description="OAuth provider to use for sign-in")
- class OrcaAuthStartResponse(BaseModel):
- """Returned by ``POST /orca-cloud/auth/start``. The frontend opens
- ``auth_url`` in a new tab. After the user signs in to Orca, they copy the
- redirected URL from their address bar and POST it to
- ``/orca-cloud/auth/finish`` to complete the handshake."""
- auth_url: str = Field(..., description="URL to open for Orca Cloud sign-in")
- class OrcaAuthFinishRequest(BaseModel):
- """Submitted by the frontend after the user pastes the callback URL from
- their browser. The URL contains a Supabase ``code`` (and our ``state``)
- that we exchange for tokens."""
- callback_url: str = Field(..., description="The full URL the browser was redirected to after sign-in")
- class OrcaAuthPasswordRequest(BaseModel):
- """Body for ``POST /orca-cloud/auth/password``. Whether this succeeds
- depends on Orca's Supabase project — their desktop client refuses
- password payloads, but the web sign-in offers email+password as one
- option. We forward the credentials and surface the server's response.
- ``email`` is plain ``str`` rather than Pydantic's ``EmailStr`` to avoid
- pulling in the optional ``email-validator`` dependency — Supabase will
- reject malformed addresses with a clear error itself, and the existing
- Bambu Cloud login schema uses the same approach."""
- email: str = Field(..., min_length=1)
- password: str = Field(..., min_length=1)
- class OrcaAuthStatusResponse(BaseModel):
- """Connection status for the Orca Cloud tab."""
- connected: bool
- email: str | None = None
- user_id: str | None = None
- class OrcaProfileMeta(BaseModel):
- """A single profile, shaped to match the Bambu Cloud ``SlicerSetting``
- schema so the frontend can render Orca profiles with the existing
- Bambu Cloud visual components (cards, filter bar, grouping). Per-source
- differences (Orca's IDs are UUIDs not Bambu's ``PFU...`` prefix; Orca
- types are ``machine`` / ``process`` / ``filament`` whereas Bambu uses
- ``printer`` / ``process`` / ``filament``) are normalized at the route
- layer before the response leaves the backend."""
- setting_id: str
- name: str
- type: str
- version: str | None = None
- user_id: str | None = None
- updated_time: str | None = None
- is_custom: bool = True
- class OrcaProfileListResponse(BaseModel):
- """Groups Orca profiles by type, matching ``SlicerSettingsResponse``."""
- filament: list[OrcaProfileMeta] = []
- printer: list[OrcaProfileMeta] = []
- process: list[OrcaProfileMeta] = []
- class OrcaProfileDetail(BaseModel):
- """Single profile's full content, shaped to match ``SlicerSettingDetail``
- so the frontend's detail modal can render it without translation."""
- setting_id: str
- name: str
- type: str
- version: str | None = None
- base_id: str | None = None
- update_time: str | None = None
- setting: dict
|