Skip to content

feat(settings): profile location - show, set and clear latitude/longitude - G36 #57

Description

@Adron

Summary

The web publishes an optional profile location (latitude / longitude) that powers its Location and Weather widgets. UserDTO decodes latitude and longitude (UserDTO.swift:92–93), the native app neither shows nor sets them, and UpdateUserRequest has no fields for them — so the value is invisible and unclearable from macOS.

What the web offers (/help/settings ▸ Profile location)

Latitude / Longitude: Optional location for your profile, used by the Weather widget and similar location-aware features

Plus a set-from-current-location action and a clear action, under a Permissions section that requests browser geolocation.

Privacy — read this before designing the UI

This publishes an approximate home location on a public profile. Treat it accordingly:

  • Opt-in only. Never prompt at launch, never as part of onboarding, never bundled into another save.
  • The pane must state plainly, in the pane itself, that the value is publicly visible on the profile.
  • Clear must always work, even if setting is unavailable — a user who set this on the web must be able to remove it from the Mac.
  • If Core Location is used for "set from current location", request when-in-use at the moment the button is pressed and never on a background path. Handle denial by leaving manual entry available, not by nagging.

Unknown to probe first

UserDTO carries a cleared: Bool? flag (UserDTO.swift:95) that hints at a server convention for clearing the value — sending null may not be how it is done. Live probe on the test account returns "cleared":true with latitude:null, longitude:null, which is consistent with "cleared" being the explicit signal rather than a null coordinate pair.

Set a location on the web, then clear it, and watch what the web sends. Do not guess: a wrong clear payload could leave a location published that the user believes they removed. That is the failure mode that matters here.

Division of labor

Kit

  • Add latitude / longitude (and whatever the clear convention turns out to be) to UpdateUserRequest.
  • Contract test covering set and clear, asserting a cleared profile really reads back as cleared.

Domain

  • Location fields on the profile-settings model, with clear modelled as its own operation rather than "write nil" — so the intent is explicit at every layer.

App

  • A Profile location section in Settings: current value, manual lat/long entry, Set from current location, Clear, and the public-visibility notice.
  • Core Location permission requested only on the button press.
  • ⚠️ The App target is sandboxed — confirm the location entitlement is present and that adding it does not disturb the existing notarization/hardened-runtime setup. If it does, ship manual entry + clear first and treat "set from current location" as a follow-up; manual entry alone already closes the invisible-and-unclearable problem.

Tests

  • happy — set a coordinate pair, read it back, see it on the profile
  • invalid — out-of-range latitude/longitude rejected client-side
  • upstream-failure — a failed clear leaves the UI showing the location as still set, never as cleared
  • boundary — clearing an already-cleared profile; a profile with a location set on the web and never touched on macOS

Acceptance criteria

  • A location set on the web is visible and clearable from the Mac.
  • No location is ever published without an explicit user action.
  • Full E2E gate green.

Notes

work-consolidation.md tracks this as G36. Size S–M. Low priority relative to the rest of the account cluster, but the "unclearable from macOS" part is a genuine privacy wart.


Probe result (2026-09-15) — re-scoped, and the setter is deliberately not shipping

The issue was explicit: "Set a location on the web, then clear it, and watch what the web sends. Do not guess: a wrong clear payload could leave a location published that the user believes they removed. That is the failure mode that matters here."

Probed. There is no clear path at all, and the cleared-flag inference in this issue is disproved. Full evidence in #91; the short version:

  • PATCH /api/user/update is the only user-mutation route (OPTIONS /api/user → GET, HEAD, OPTIONS; no /api/user/location).
  • Setting works: {"latitude":47.6062,"longitude":-122.3321} → 200.
  • Every unset form — null, "", "null", false, out-of-range — is 400 latitude must be a number between -90 and 90.
  • Every speculative clear key (clearLocation, location:null, cleared:true) returns 200 and changes nothing, which is worse than a rejection.
  • DELETE /api/user/location → 404.

On cleared: this issue reasoned that "cleared":true alongside null coordinates was "consistent with 'cleared' being the explicit signal". It was correlation, not mechanism — setting a location leaves cleared at true, and writing cleared:true clears nothing. In the live OpenAPI it sits among spamScore, spamReasons, signupIp — a moderation field that happens to share a name with what a clear flag would be called.

Why the setter is not shipping

This issue calls the situation "a genuine privacy wart", and it is right — but the wart is unclearable, not invisible. Shipping "set" without "clear" would make macOS a way to publish an approximate home location on a public profile that the user cannot then remove from anywhere. That is strictly worse than today.

Its own acceptance criterion says so: "Clear must always work, even if setting is unavailable." Clear cannot work. So setting does not ship either.

Re-scoped macOS work

In scope now — the read-only half, folded into the Profile settings pane (#46) rather than a standalone PR, since it is the same pane:

This closes the "invisible" half of the complaint — a location set elsewhere becomes visible on the Mac — without widening the "unclearable" half.

Blocked on #91: manual lat/long entry, Set from current location (and with it the Core Location entitlement question), and Clear. They land together, because clear is the one that makes the others safe.

⚠️ The test account now has a location it cannot lose

The probe set 47.6062 / −122.3321 on the .env contract-test account and could not undo it. That is the bug reproduced, not carelessness — but it does need clearing out of band. Noted on #91.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    blockedCannot proceed — backend-gated or spike-firstenhancementNew feature or requestparityWeb-parity gap with the InterlinedList web app

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions