maziggy
18d534c945
feat(orca-cloud): integrate Orca Cloud profile sync across UI, slicer and SpoolBuddy
Reads, lists, and slices with profiles from a user's Orca Cloud account
(OrcaSlicer 2.4.0-alpha's Supabase-backed sync) alongside the existing
Bambu Cloud integration. Four sign-in providers (Google / Apple / GitHub /
email+password); password defaults. Paste-flow PKCE because Orca's
Supabase project only allowlists localhost redirect_to — open feature
request at OrcaSlicer/OrcaSlicer#14028.
Surfaces:
- Profiles tab: new "Orca Cloud" tab next to "Bambu Cloud" with the same
rich layout (search + 5 filter dropdowns + 3-column grouped grid +
read-only detail modal)
- SliceModal: 4-tier preset picker (orca_cloud > local > bambu cloud >
standard); separate status banner per cloud; metadata-aware pre-pick
scores Orca filaments above local (Orca's sync_pull returns full
content inline so filament_type / filament_colour come for free, no
per-setting fetch rate-limit dance)
- ConfigureAmsSlotModal: orca_cloud as a new preset source (prefixed
orca_<UUID> to match local_/builtin_); generic Bambu filament-ID
derivation from parsed material (printer firmware can't grok Orca
UUIDs); slot mapping persists preset_source='orca_cloud'
- SpoolForm / SpoolBuddyWriteTagPage: Orca filaments merge into the
cloud preset list via Promise.allSettled (OrcaProfileMeta is
structurally identical to SlicerSetting)
Backend:
- services/orca_cloud.py: OrcaCloudService with PKCE / token exchange /
single-use refresh rotation / get_user_info / list_profiles via the
bare /sync/pull bootstrap path
- routes/orca_cloud.py: 7 endpoints (auth/start, auth/finish,
auth/password, status, logout, profiles, profiles/{id}); router-level
_cloud_api_key_gate + per-route cloud_caller() so API-keyed callers
(SpoolBuddy kiosk) properly resolve their owner User; just-in-time
refresh with atomic persist-before-API-call
- routes/slicer_presets.py: _fetch_orca_cloud_presets mirrors the Bambu
Cloud fetcher (status vocabulary, 5min cache, permission shortcut);
_dedupe_by_name extended to 4 tiers; UnifiedPresetsResponse gains
orca_cloud + orca_cloud_status
- services/preset_resolver.py: PresetRef.source extended with
"orca_cloud"; _resolve_orca_cloud walks list + filters
- 8 columns on users table for tokens (5 persistent) + transient PKCE
handshake state with 10-min TTL (3); dialect-branched DATETIME /
TIMESTAMP; auth-disabled mode falls back to Settings table
- orca_cloud:auth permission folded into can_access_cloud API-key scope
(same trust dimension)
2026-06-04 15:50:44 +02:00
..
2026-06-04 15:50:44 +02:00
2025-12-11 10:03:40 +01:00
2026-06-04 11:30:26 +02:00
2026-04-26 09:40:02 +02:00
2026-02-21 11:35:18 +01:00
2026-02-21 10:01:26 +01:00
2026-06-03 10:14:57 +02:00
2026-04-27 16:14:31 +02:00
2026-05-30 13:49:09 +02:00
2026-05-14 08:58:33 +02:00
2026-03-20 14:18:24 +01:00
2026-02-21 10:39:18 +01:00
2026-05-22 10:02:41 +02:00
2026-04-27 16:32:10 +02:00
2026-04-17 08:38:22 +02:00
2026-03-07 10:13:40 +01:00
2026-04-18 08:14:53 +02:00
2026-05-24 12:51:24 +02:00
2026-02-16 15:46:32 +01:00
2026-05-08 09:01:51 +02:00
2026-05-15 15:43:37 +02:00
2026-05-08 11:52:42 +02:00
2026-05-24 10:16:30 +02:00
2026-04-11 11:14:54 +02:00
2026-04-26 14:24:28 +02:00
2026-05-29 10:55:41 +02:00
2026-05-24 08:49:21 +02:00
2026-05-28 08:40:43 +02:00
2026-05-15 10:06:55 +02:00
2026-04-27 16:02:40 +02:00
2026-04-27 16:32:10 +02:00
2026-05-11 12:27:41 +02:00
2026-05-03 08:12:36 +02:00
2026-04-24 16:02:55 +02:00
2026-02-07 19:01:04 +02:00
2026-05-08 14:06:40 +02:00
2026-05-16 14:35:47 +02:00
2026-04-11 11:33:49 +02:00
2026-06-02 14:51:08 +02:00
2026-04-22 11:14:42 +02:00
2026-06-02 14:51:08 +02:00
2026-05-22 10:22:14 +02:00
2026-06-04 10:17:10 +02:00
2026-02-06 12:19:17 +01:00
2026-04-26 10:01:17 +02:00
2026-03-19 08:40:24 +01:00
2026-04-28 13:58:56 +02:00
2026-04-24 16:48:59 +02:00
2026-06-02 10:02:17 +02:00
2026-06-02 10:02:17 +02:00
2026-06-02 12:42:16 +02:00
2026-05-21 08:45:59 +02:00
2026-04-13 09:54:26 +02:00
2026-05-15 08:50:37 +02:00
2026-05-15 08:50:37 +02:00
2026-05-15 08:50:37 +02:00
2026-05-15 08:50:37 +02:00
2026-05-08 11:52:42 +02:00
2026-03-03 13:34:03 +01:00
2026-05-13 13:23:21 +02:00
2026-03-31 12:13:58 +02:00
2026-03-07 09:17:26 +01:00
2026-04-22 17:48:53 +02:00
2026-02-06 12:19:17 +01:00
2026-04-29 11:17:43 +02:00
2026-05-17 09:30:02 +02:00
2026-02-15 13:14:15 +01:00
2026-03-18 11:13:27 +01:00
2026-05-20 08:12:17 +02:00
2026-04-08 08:17:42 +02:00
2026-05-11 14:08:23 +02:00
2026-05-22 12:34:08 +02:00
2026-05-21 08:30:17 +02:00
2026-05-04 10:34:36 +02:00
2026-05-29 11:18:06 +02:00
2026-05-05 16:00:22 +02:00
2026-06-02 10:02:17 +02:00
2026-05-19 10:53:36 +02:00
2026-04-07 09:20:58 +02:00
2026-05-25 09:04:47 +02:00
2026-06-02 12:12:54 +02:00
2026-05-24 09:18:38 +02:00
2026-03-14 15:06:07 +01:00
2026-03-20 11:34:23 +01:00
2026-04-13 09:12:12 +02:00
2026-04-28 17:19:17 +02:00
2026-05-23 08:47:46 +02:00
2026-02-22 16:43:16 +01:00
2026-05-20 11:25:45 +02:00
2026-05-24 09:18:38 +02:00
2026-05-16 09:05:05 +02:00
2026-04-24 13:24:00 +02:00
2026-05-14 15:28:41 +02:00
2026-05-06 09:42:15 +02:00
2026-06-04 15:50:44 +02:00
2026-02-10 09:38:06 +01:00
2026-04-20 17:32:34 +02:00
2026-04-29 09:13:33 +02:00
2026-04-25 13:24:49 +02:00
2026-05-12 16:02:24 +02:00
2026-05-08 11:52:42 +02:00
2026-05-08 14:28:41 +02:00
2026-03-26 16:35:29 +01:00
2026-04-09 08:16:54 +02:00
2026-05-08 11:52:42 +02:00
2026-05-18 08:51:27 +02:00
2026-05-17 09:10:20 +02:00
2026-05-12 08:48:30 +02:00
2026-05-20 11:00:54 +02:00
2026-05-08 11:52:42 +02:00
2026-05-08 11:52:42 +02:00
2026-05-22 09:05:25 +02:00
2026-05-22 16:31:16 +02:00
2026-02-15 15:47:41 +01:00
2026-05-21 13:49:20 +02:00
2026-05-24 12:30:12 +02:00
2026-05-12 09:20:53 +02:00
2026-04-26 14:24:28 +02:00
2026-05-15 08:50:37 +02:00
2026-06-03 09:45:10 +02:00
2026-03-17 12:24:36 +01:00
2026-05-30 13:34:10 +02:00
2026-05-30 13:34:10 +02:00
2026-03-18 09:04:31 +01:00
2026-05-30 13:34:10 +02:00
2026-06-02 14:33:20 +02:00
2026-06-04 11:24:20 +02:00
2026-05-30 13:34:10 +02:00
2026-06-03 10:04:37 +02:00