feat(api): add DELETE /api/profile with Garmin client/tokenstore teardown
This commit is contained in:
@@ -75,3 +75,29 @@ func (s *Server) handleUpdateProfile(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
writeJSON(w, http.StatusOK, updated)
|
||||
}
|
||||
|
||||
// handleDeleteProfile permanently deletes the signed-in user's entire
|
||||
// geniusrun account (profile, workout kinds/paces, activities and
|
||||
// everything under them, sync state/runs -- see schema.sql's ON DELETE
|
||||
// CASCADE from users(id)) and tears down their cached Garmin client and
|
||||
// token-store directory. It does not touch the session cookie itself --
|
||||
// the frontend follows a successful call with a real logout navigation
|
||||
// (see docs/superpowers/specs/2026-07-26-profile-deletion-design.md).
|
||||
func (s *Server) handleDeleteProfile(w http.ResponseWriter, r *http.Request) {
|
||||
userID := userIDFromContext(r.Context())
|
||||
|
||||
s.mu.Lock()
|
||||
inProgress := s.userSyncRunning[userID]
|
||||
s.mu.Unlock()
|
||||
if inProgress {
|
||||
writeError(w, http.StatusConflict, "a sync is in progress for this account; wait for it to finish before deleting your profile")
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.DB.DeleteUser(r.Context(), userID); err != nil {
|
||||
writeError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
s.removeGarminClient(userID)
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user