Repository navigation
feat(settings): profile location - show, set and clear latitude/longitude - G36 #57
Description
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-useat 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) toUpdateUserRequest. - 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/updateis 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 — is400 latitude must be a number between -90 and 90. - Every speculative clear key (
clearLocation,location:null,cleared:true) returns200and 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:
- Show the coordinates when the account has them, with the plain statement that they are publicly visible.
- Say honestly that removing them is not currently possible, and link to upstream: a profile location can be set through the API but never cleared #91 rather than offering a control that cannot work.
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
Adron commentedon Sep 16, 2026
Read-only half shipped (PR #92) — the rest is blocked on #91
Recording where this stands so the next reader does not have to reconstruct it.
Shipped
Settings ▸ Profile now shows a published location, with the plain statement that it is publicly visible and that it cannot be removed from the app, linked to #91. That closes the "invisible" half of this issue's complaint: a location set on the web is visible on the Mac.
There is a test asserting that no coordinate ever reaches a PATCH body, because the failure mode that matters here is writing one by accident.
Blocked, and deliberately so
Manual lat/long entry, Set from current location, and Clear all wait on #91: a location can be set through this API and cleared through nothing. Every unset form is a
400; every speculative clear key returns200and changes nothing.This issue's own acceptance criterion settles the sequencing — "Clear must always work, even if setting is unavailable." Clear cannot work, so setting does not ship either.
Two things that fall out of that, and are therefore not open questions any more:
clearedflag inference in this issue's body is disproved — see upstream: a profile location can be set through the API but never cleared #91. It is correlation, not mechanism: setting a location leavesclearedattrue, and writingcleared: trueclears nothing. In the live OpenAPI it sits amongspamScore,spamReasonsandsignupIp.What we need from you
Nothing on this issue. Answer #91 and this becomes a small, well-understood piece of work.