Skip to content

Feedback

LaunchSwift includes a feedback form feature wired to POST /api/feedback.

  • ios/SwiftLaunch/Features/Feedback/FeedbackState.swift — request, draft, and submission state
  • ios/SwiftLaunch/Features/Feedback/Models/FeedbackModels.swiftFeedbackCategory, SubmissionStatus
  • ios/SwiftLaunch/Features/Feedback/FeedbackAccessPolicy.swift — auth and submit guards
  • ios/SwiftLaunch/Features/Feedback/Views/FeedbackView.swift — form UI
  • backend/src/routes/feedback.ts — feedback API route
@MainActor
@Observable
final class FeedbackState {
var feedbackText = ""
var email = ""
var category: FeedbackCategory = .general
var submissionStatus: SubmissionStatus = .idle
var isSubmitting = false
func submit() async
func resetAfterDismissal()
func preserveDraftForAuthRedirect()
}

FeedbackState also persists draft text/email/category to UserDefaults, with scope-aware behavior for guest vs authenticated sessions.

enum FeedbackCategory: String, CaseIterable, Identifiable, Sendable {
case general
case bug
case feature
}
enum SubmissionStatus: Equatable, Sendable {
case idle
case error(String)
case success
}

FeedbackAccessPolicy requires authentication for feedback actions:

  • canUseFeedbackActions(isAuthenticated:)
  • canSubmit(draft:isSubmitting:isAuthenticated:)

If signed out, FeedbackView prompts sign-in and redirects through AppRouter.

backend/src/index.ts mounts feedbackRoutes under /api, so the route is:

MethodPathAuth
POST/api/feedbackRequired (protectedRoute)

Request body accepted by feedback.ts:

{
"category": "bug",
"text": "The chat screen freezes when switching models",
"email": "user@example.com",
"deviceInfo": "iOS 18.2 on iPhone"
}

Notes:

  • deviceInfo can be either a string or an object; objects are JSON-stringified server-side.
  • With D1 available, feedback is inserted into the feedback table.
  • Success response is { "success": true } with HTTP 201.

The current Settings screen links directly to FeedbackView via NavigationLink in:

  • ios/SwiftLaunch/Features/Settings/SettingsView.swift