docs(apple): add macOS-first conversion review and roadmap#5
docs(apple): add macOS-first conversion review and roadmap#5zachyzissou wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a macOS-first “Apple ecosystem conversion plan” document to guide an Apple-native rewrite of OmniFeed while maximizing reuse for a later iOS target.
Changes:
- Introduces a current-state review (strengths/gaps) aimed at native Apple clients.
- Proposes an Apple-first macOS architecture (SwiftUI/Observation/SwiftData/etc.) and module layout.
- Lays out a phased roadmap with risks/mitigations and immediate next actions.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ## 3) macOS-first delivery roadmap | ||
|
|
||
| ## Phase 0 — hardening backend for native clients (1-2 weeks) | ||
|
|
||
| - Add a formal API schema (OpenAPI recommended). | ||
| - Ensure stable error envelopes include `requestId` consistently. | ||
| - Replace mock workflow adapter output with production adapters or explicit feature flags. | ||
| - Add endpoint contract tests for feeds/settings/filter workflows. | ||
|
|
||
| **Exit criteria:** API is stable enough for generated/strict typed Swift clients. | ||
|
|
||
| ## Phase 1 — macOS MVP (2-4 weeks) | ||
|
|
||
| - Create `OmniFeedMac` SwiftUI app target. | ||
| - Implement these screens: | ||
| - Feed dashboard (music/news/podcasts/videos) | ||
| - Filter list/create/update/delete | ||
| - Onboarding wizard/settings | ||
| - Networking via `URLSession` async/await and DTO decoding. | ||
| - Local feed/settings persistence via SwiftData. | ||
| - Structured client logs via `Logger`. | ||
|
|
||
| **Exit criteria:** macOS app reaches feature parity with current dashboard essentials. | ||
|
|
||
| ## Phase 2 — Apple platform integrations (1-2 weeks) | ||
|
|
||
| - Add App Intents: | ||
| - Refresh all feeds | ||
| - Open specific feed section | ||
| - Trigger workflow endpoint safely | ||
| - Add WidgetKit summary widget for top feed cards. | ||
| - Add notifications (new content digest, workflow failures if surfaced). | ||
|
|
||
| **Exit criteria:** macOS app is deeply integrated with system experiences. | ||
|
|
||
| ## Phase 3 — iOS expansion from shared modules (2-3 weeks) | ||
|
|
||
| - Add iOS target reusing shared Core + Features packages. | ||
| - Keep platform-specific shell and navigation differences only. | ||
| - Reuse App Intents where possible, adapt widget families per platform. | ||
|
|
||
| **Exit criteria:** iOS app launched with high shared-code percentage and minimal duplicate logic. |
There was a problem hiding this comment.
In section "3) macOS-first delivery roadmap", the phase headers are written as ## Phase 0/1/2/3, which makes them the same heading level as the parent section and breaks the document hierarchy/TOC. Consider demoting these to ### (or ####) so they nest under "## 3)" consistently.
| - App Intents overview: https://developer.apple.com/documentation/AppIntents/app-intents | ||
| - Creating first app intent: https://developer.apple.com/documentation/appintents/creating-your-first-app-intent | ||
| - SwiftData device sync: https://developer.apple.com/documentation/swiftdata/syncing-model-data-across-a-persons-devices | ||
| - WidgetKit overview: https://developer.apple.com/documentation/WidgetKit/ |
There was a problem hiding this comment.
The Apple reference URLs use inconsistent path casing (e.g., documentation/AppIntents and documentation/WidgetKit vs lowercase variants). On case-sensitive hosts this can lead to broken links; it’s safer to use the canonical lowercase paths consistently (e.g., /documentation/appintents/..., /documentation/widgetkit/...).
| - App Intents overview: https://developer.apple.com/documentation/AppIntents/app-intents | |
| - Creating first app intent: https://developer.apple.com/documentation/appintents/creating-your-first-app-intent | |
| - SwiftData device sync: https://developer.apple.com/documentation/swiftdata/syncing-model-data-across-a-persons-devices | |
| - WidgetKit overview: https://developer.apple.com/documentation/WidgetKit/ | |
| - App Intents overview: https://developer.apple.com/documentation/appintents/app-intents | |
| - Creating first app intent: https://developer.apple.com/documentation/appintents/creating-your-first-app-intent | |
| - SwiftData device sync: https://developer.apple.com/documentation/swiftdata/syncing-model-data-across-a-persons-devices | |
| - WidgetKit overview: https://developer.apple.com/documentation/widgetkit/ |
|
|
||
| ### Networking and request correlation | ||
|
|
||
| - Include `x-request-id` in every request and log both request and response IDs. |
There was a problem hiding this comment.
The "Networking and request correlation" bullet says to "log both request and response IDs", but the backend appears to use a single x-request-id value that is echoed back in the response header. To avoid confusion, consider rephrasing to explicitly say the client should generate/forward x-request-id and then log the same value from the response header for correlation (rather than implying two distinct IDs).
| - Include `x-request-id` in every request and log both request and response IDs. | |
| - Generate or forward `x-request-id` in every request, then log that same value from the echoed response header for end-to-end correlation. |
Motivation
Description
docs/APPLE_ECOSYSTEM_CONVERSION_PLAN.mdwhich contains a current-state code review, identified gaps (mock workflow adapter, missing API contract, frontend lint debt, web-centric caching), an Apple-first architecture (SwiftUI, Observation, SwiftData, URLSession, App Intents, WidgetKit, UserNotifications, Keychain, OSLog), a phased roadmap (backend hardening, macOS MVP, platform integrations, iOS expansion), risks/mitigations, and immediate next actions and references.Testing
cd backend && npm testwhich passed (2 test suites, 6 tests), and ran frontend lint withcd frontend && npm run lintwhich failed due to a single@typescript-eslint/no-explicit-anyerror infrontend/src/components/FilterBuilder.tsx.Codex Task