Client applications
Shared philosophy
Section titled “Shared philosophy”The golfer-facing clients mirror the same workflow and JSON contract:
- capture or select a lie photo
- submit the context to the API
- display the returned recommendation immediately
- read the recommendation aloud
Clubhouse web app
Section titled “Clubhouse web app”- Built with React 19, TypeScript, PrimeReact, SCSS, Axios, and React Router.
- API access lives under
clubhouse/src/api. - Shared contracts live in
clubhouse/src/types/index.ts. - Pages live in
clubhouse/src/pages.
Upload example
Section titled “Upload example”const { data } = await apiClient.post<Photo>('/photos/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' },});iOS client
Section titled “iOS client”- Built with SwiftUI.
Models/Models.swiftmirrors the web contracts.Networking/APIClient.swiftis the native equivalent of the shared Axios client.Features/Upload/UploadView.swiftpreserves the same upload and spoken-output flow.
Networking example
Section titled “Networking example”func post<T: Decodable>(_ path: String, query: [URLQueryItem] = []) async throws -> T { var request = URLRequest(url: try makeURL(path: path, query: query)) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") return try decode(try await send(request), as: T.self)}Android client
Section titled “Android client”- Built with Kotlin and Jetpack Compose.
model/Models.ktmirrors the iOS and web models.network/ApiClient.ktmirrors the web and iOS transport layer.feature/upload/UploadScreen.ktis the on-course capture flow.
Networking example
Section titled “Networking example”suspend fun postString(path: String, query: List<Pair<String, String>> = emptyList()): String = execute(Request.Builder().url(buildUrl(path, query)).post(emptyBody).build()).decodeToString()Why mirroring matters
Section titled “Why mirroring matters”Parallel structures reduce cognitive load when implementing features across surfaces. A developer can often infer the corresponding code location in another client by understanding the naming and layout in the first one.