feat: native give-feedback iOS app (FeedbackKit + FeedbackPortalApp)#2
Merged
Conversation
Two-track program: a public end-user API added to OpenCoven/feedback (anonymous reads + better-auth bearer writes, reusing existing services) and a native SwiftUI give-feedback app that consumes it via an OpenAPI-generated client. Captures the audit (v1 API is admin/API-key only; end-user surface is web-rendered), the resolved forks (end-user app, full feature set, web access yes, email-OTP bearer auth, 4-tab nav), and API-first sequencing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Track 1 (OpenCoven/feedback): 12 TDD tasks adding /api/public/v1 — portal-session bearer auth, anonymous reads, authed writes, public OpenAPI — reusing existing domain services. Track 2 (feedback-mobile): 14 TDD tasks for FeedbackKit (typed client, AuthStore, view models, cache) + a SwiftUI 4-tab FeedbackPortalApp, with view models tested against a mock so the app can be built before the live API exists. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…alApp iOS 17 target Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces a new native iOS “give feedback” app architecture by adding a reusable SwiftPM library (FeedbackKit) that encapsulates API/auth/view-model logic (unit-testable on macOS), plus a thin SwiftUI iOS app target (FeedbackPortalApp) that wires UI screens over that kit. It also adds design/implementation docs and CI to run tests/lint and build the app.
Changes:
- Add
FeedbackKitSwiftPM library with models, API client, auth/token storage, offline cache, and SwiftUI-facing view models (plus extensive unit tests). - Add
FeedbackPortalAppSwiftUI iOS app target via XcodeGen (project.yml) with 4-tab shell and key screens (feed, detail, submit, changelog, help, account/sign-in). - Add housekeeping and tooling: SwiftLint config fixes, CI workflow, and docs/specs/plans for Track 1/2.
Reviewed changes
Copilot reviewed 47 out of 48 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| Tests/OpenCovenFeedbackTests/OpenCovenFeedbackEventTests.swift | Makes event tests concurrency-safe using locked counters/logs. |
| Tests/FeedbackKitTests/TokenStoreTests.swift | Adds unit test coverage for token storage behavior. |
| Tests/FeedbackKitTests/SubmitViewModelTests.swift | Adds submit flow tests (validation + auth gating). |
| Tests/FeedbackKitTests/SmokeTests.swift | Adds a basic module-load smoke test for FeedbackKit. |
| Tests/FeedbackKitTests/ReadOnlyViewModelsTests.swift | Adds tests for changelog/help read-only view models. |
| Tests/FeedbackKitTests/ProtocolConformanceTests.swift | Verifies mock conformance and records/mock behaviors. |
| Tests/FeedbackKitTests/PostDetailViewModelTests.swift | Adds detail/vote sign-in gate tests. |
| Tests/FeedbackKitTests/ModelsTests.swift | Adds JSON decoding tests for envelopes/pages and models. |
| Tests/FeedbackKitTests/MockFeedbackAPI.swift | Adds a configurable mock FeedbackAPI implementation for tests. |
| Tests/FeedbackKitTests/HTTPFeedbackAPITests.swift | Adds URLSession/URLProtocol tests for the HTTP API client. |
| Tests/FeedbackKitTests/HTTPAuthServiceTests.swift | Adds URLProtocol-based tests for email-OTP auth HTTP client. |
| Tests/FeedbackKitTests/FeedViewModelTests.swift | Adds feed loading and cache-fallback tests. |
| Tests/FeedbackKitTests/ContentCacheTests.swift | Adds disk cache round-trip tests. |
| Tests/FeedbackKitTests/AuthStoreTests.swift | Adds tests for sign-in/out state and token persistence wiring. |
| Sources/FeedbackKit/Models/Models.swift | Introduces public Codable domain models + envelope/page types + JSON decoder. |
| Sources/FeedbackKit/FeedbackKit.swift | Adds a minimal FeedbackKit entry point. |
| Sources/FeedbackKit/Features/Submit/SubmitViewModel.swift | Adds submit view model with validation and auth gating. |
| Sources/FeedbackKit/Features/Help/HelpViewModel.swift | Adds help categories view model with offline read cache fallback. |
| Sources/FeedbackKit/Features/Feed/FeedViewModel.swift | Adds feed view model with loading/error and cache fallback. |
| Sources/FeedbackKit/Features/Detail/PostDetailViewModel.swift | Adds post detail view model (load/comments/vote/comment with gating). |
| Sources/FeedbackKit/Features/Changelog/ChangelogViewModel.swift | Adds changelog view model with offline read cache fallback. |
| Sources/FeedbackKit/Config/AppConfig.swift | Adds a minimal config container (instance URL). |
| Sources/FeedbackKit/Cache/ContentCache.swift | Adds read-only disk cache for feed/changelog/help. |
| Sources/FeedbackKit/Auth/TokenStore.swift | Adds token store protocol + in-memory + Keychain implementations. |
| Sources/FeedbackKit/Auth/HTTPAuthService.swift | Adds email-OTP HTTP auth client. |
| Sources/FeedbackKit/Auth/AuthStore.swift | Adds observable auth state store over an AuthService + TokenStore. |
| Sources/FeedbackKit/API/HTTPFeedbackAPI.swift | Adds URLSession-based implementation of FeedbackAPI with error mapping. |
| Sources/FeedbackKit/API/FeedbackAPI.swift | Adds the public FeedbackAPI protocol and PostSort. |
| Sources/FeedbackKit/API/APIError.swift | Adds typed API error model used across the kit. |
| project.yml | Adds XcodeGen target + scheme for FeedbackPortalApp. |
| Package.swift | Adds FeedbackKit product/targets and macOS platform support. |
| docs/superpowers/specs/2026-05-28-native-give-feedback-app-design.md | Adds design spec for the native app + public API approach. |
| docs/superpowers/plans/2026-05-28-track2-native-ios-app.md | Adds Track 2 implementation plan (native iOS app). |
| docs/superpowers/plans/2026-05-28-track1-public-api.md | Adds Track 1 implementation plan (public end-user API). |
| App/FeedbackPortalApp/SubmitView.swift | Adds SwiftUI submit screen + sign-in sheet presentation wiring. |
| App/FeedbackPortalApp/SignInSheet.swift | Adds SwiftUI email-OTP sign-in sheet UI. |
| App/FeedbackPortalApp/RootTabView.swift | Adds 4-tab app shell. |
| App/FeedbackPortalApp/PostDetailView.swift | Adds SwiftUI post detail screen (vote/comment) + sign-in gating. |
| App/FeedbackPortalApp/Info.plist | Adds Info.plist for the new app target and instance URL config key. |
| App/FeedbackPortalApp/HelpTabView.swift | Adds SwiftUI help categories screen. |
| App/FeedbackPortalApp/FeedTabView.swift | Adds SwiftUI feed list + navigation to detail + submit sheet. |
| App/FeedbackPortalApp/FeedbackPortalApp.swift | Adds the @main SwiftUI app entry point. |
| App/FeedbackPortalApp/Environment.swift | Adds composition root (API/auth initialization and token plumbing). |
| App/FeedbackPortalApp/ChangelogTabView.swift | Adds SwiftUI changelog screen. |
| App/FeedbackPortalApp/AccountTabView.swift | Adds account tab (sign-in/out entry points). |
| .swiftlint.yml | Fixes SwiftLint config keys and includes App/. |
| .gitignore | Ignores .superpowers/ artifacts. |
| .github/workflows/ci.yml | Adds CI: swift test, SwiftLint, iOS simulator builds for kit + app. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A standalone native SwiftUI give-feedback app, built on the new public end-user API (
OpenCoven/feedback#2). End users browse boards, vote, comment, submit, and read changelog + help — all live from the API, with email-OTP bearer auth and an offline read cache. Independent of the embeddableOpenCovenFeedbackwidget SDK.Implements Track 2 of the design at
docs/superpowers/specs/2026-05-28-native-give-feedback-app-design.md(Architecture C). Design + both implementation plans are included in this branch.What's here
FeedbackKit(new SPM library — all logic, fully unit-tested, 68 tests):FeedbackAPIprotocol +HTTPFeedbackAPI(URLSession, bearer header, 401/404/429 error mapping) — tested viaURLProtocolstubsAuthStore+HTTPAuthService(better-auth email-OTP) +TokenStore(Keychain + in-memory)@MainActor/ObservableObjectwith loading/error states, tested against a mockFeedbackAPIContentCache— read-only offline fallback for feed/changelog/helpFeedbackPortalApp(SwiftUI iOS app,App/FeedbackPortalApp/): 4-tab shell (Feedback · Changelog · Help · Account), post detail, submit sheet, sign-in sheet. Thin glue over FeedbackKit.Housekeeping: fixed
.swiftlint.ymlinvalid keys (included_paths→included), removed a deadFeedbackAppTeststarget, added CI.Built API-first
View models depend only on the
FeedbackAPIprotocol and are tested with a mock, so the app was built before the live API exists. The HTTP client/auth-service have inline NOTEs flagging the exact better-auth OTP endpoint paths to confirm against a running instance.Test plan
swift test— 68 FeedbackKit tests pass; existing OpenCovenFeedback SDK tests untouched (41) → 109 totalswiftlint --strict— 0 violations across 54 filesxcodegen generateproduces theFeedbackPortalAppschemeswift test+ SwiftLint (macos-14) and iOS builds of FeedbackKit + FeedbackPortalApp (macos-15) — first run on this PR🤖 Generated with Claude Code