prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Investigate missing event properties
  In #1057 we made some changes to the base `Event` type, to include an `eligibility_types` property on all events we send into Amplitude.
  
  ## OAuth events
  
  Looking at the event reports over the last 14 days of production data, the [`started sign in` event](https://github.com/cal-itp/benefits/blob/dev/benefits/oauth/analytics.py#L16) is missing the `eligibility_types` property in 100% of recorded events. [See report here](https://data.amplitude.com/compiler/Benefits/events/main/latest/started%20sign%20in).
  
  ## Eligibility events
  
  We're also seeing unexpected behavior with the `eligibility` events for `courtesy_card`: the `eligiblity_types` property is coming through with the `event_properties`, but not with `user_properties`, leading to blanks/`(none)` when plotting the events on user-based charts. 
  
  For example, this [user checked `courtesy_card` eligibility](https://analytics.amplitude.com/compiler/project/304110/search/amplitude_id%3D555656738955?collapsed=true&sessionHandle=YXoogID_YXoogIG_IFfuPiL_BKPu_2b6a1cea-210a-8693-6f25-38c5de0f39c3&eventId=b505e207-9ca1-11ed-967a-9bb610a8bd25) and we can see the value in the raw `event_properties` output, but not `user_properties`:
  
  ```json
  {
    "amplitude_id": 555656738955,
    "app": 304110,
    "client_event_time": "2023-01-25 11:16:23.396000",
    "client_upload_time": "2023-01-25 11:16:23.506000",
    "data_type": "event",
    "display_name": "started eligibility",
    "event_id": 664,
    "event_properties": {
      "eligibility_types": [
        "courtesy_card"
      ],
      "eligibility_verifier": "MST Courtesy Card Eligibility Server Verifier",
      "path": "/eligibility/confirm",
      "transit_agency": "Monterey-Salinas Transit"
    },
    "event_time": "2023-01-25 11:16:23.396000",
    "event_type": "started eligibility",
    "language": "English",
    "library": "http/2.0",
    "server_received_time": "2023-01-25 11:16:23.506000",
    "server_upload_time": "2023-01-25 11:16:23.508000",
    "session_id": 1674645209603,
    "source_id": null,
    "start_version": "2023.01.1",
    "timeline_hidden": false,
    "user_creation_time": "2023-01-25 11:13:29.606000",
    "user_id": "35aabc7e-d98c-451d-95ec-e4033fcec987",
    "user_properties": {
      "eligibility_verifier": "MST Courtesy Card Eligibility Server Verifier",
      "referrer": "https://benefits.calitp.org/eligibility/confirm",
      "referring_domain": "benefits.calitp.org",
      "transit_agency": "Monterey-Salinas Transit",
      "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
    },
    "uuid": "b505e207-9ca1-11ed-967a-9bb610a8bd25",
    "version_name": "2023.01.1"
  }
  ```
  
  And the resulting user chart shows categorizes this event as `(none)`:
  
  <img width="680" alt="image" src="https://user-images.githubusercontent.com/1783439/215842237-10a52ea7-5bad-4fa2-ad08-004e01d1f174.png">
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `benefits/eligibility/analytics.py`
  Content:
  ```
  1 """
  2 The eligibility application: analytics implementation.
  3 """
  4 from benefits.core import analytics as core
  5 
  6 
  7 class EligibilityEvent(core.Event):
  8     """Base analytics event for eligibility verification."""
  9 
  10     def __init__(self, request, event_type, eligibility_types):
  11         super().__init__(request, event_type)
  12         # overwrite core.Event eligibility_types
  13         self.update_event_properties(eligibility_types=eligibility_types)
  14 
  15 
  16 class SelectedVerifierEvent(EligibilityEvent):
  17     """Analytics event representing the user selecting an eligibility verifier."""
  18 
  19     def __init__(self, request, eligibility_types):
  20         super().__init__(request, "selected eligibility verifier", eligibility_types)
  21 
  22 
  23 class StartedEligibilityEvent(EligibilityEvent):
  24     """Analytics event representing the beginning of an eligibility verification check."""
  25 
  26     def __init__(self, request, eligibility_types):
  27         super().__init__(request, "started eligibility", eligibility_types)
  28 
  29 
  30 class ReturnedEligibilityEvent(EligibilityEvent):
  31     """Analytics event representing the end of an eligibility verification check."""
  32 
  33     def __init__(self, request, eligibility_types, status, error=None):
  34         super().__init__(request, "returned eligibility", eligibility_types)
  35         status = str(status).lower()
  36         if status in ("error", "fail", "success"):
  37             self.update_event_properties(status=status, error=error)
  38         if status == "success":
  39             self.update_user_properties(eligibility_types=eligibility_types)
  40 
  41 
  42 def selected_verifier(request, eligibility_types):
  43     """Send the "selected eligibility verifier" analytics event."""
  44     core.send_event(SelectedVerifierEvent(request, eligibility_types))
  45 
  46 
  47 def started_eligibility(request, eligibility_types):
  48     """Send the "started eligibility" analytics event."""
  49     core.send_event(StartedEligibilityEvent(request, eligibility_types))
  50 
  51 
  52 def returned_error(request, eligibility_types, error):
  53     """Send the "returned eligibility" analytics event with an error status."""
  54     core.send_event(ReturnedEligibilityEvent(request, eligibility_types, status="error", error=error))
  55 
  56 
  57 def returned_fail(request, eligibility_types):
  58     """Send the "returned eligibility" analytics event with a fail status."""
  59     core.send_event(ReturnedEligibilityEvent(request, eligibility_types, status="fail"))
  60 
  61 
  62 def returned_success(request, eligibility_types):
  63     """Send the "returned eligibility" analytics event with a success status."""
  64     core.send_event(ReturnedEligibilityEvent(request, eligibility_types, status="success"))
  65
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/benefits/eligibility/analytics.py b/benefits/eligibility/analytics.py
  --- a/benefits/eligibility/analytics.py
  +++ b/benefits/eligibility/analytics.py
  @@ -11,6 +11,7 @@
           super().__init__(request, event_type)
           # overwrite core.Event eligibility_types
           self.update_event_properties(eligibility_types=eligibility_types)
  +        self.update_user_properties(eligibility_types=eligibility_types)
   
   
   class SelectedVerifierEvent(EligibilityEvent):
  
verification_info: {"golden_diff": "diff --git a/benefits/eligibility/analytics.py b/benefits/eligibility/analytics.py\n--- a/benefits/eligibility/analytics.py\n+++ b/benefits/eligibility/analytics.py\n@@ -11,6 +11,7 @@\n         super().__init__(request, event_type)\n         # overwrite core.Event eligibility_types\n         self.update_event_properties(eligibility_types=eligibility_types)\n+        self.update_user_properties(eligibility_types=eligibility_types)\n \n \n class SelectedVerifierEvent(EligibilityEvent):\n", "issue": "Investigate missing event properties\nIn #1057 we made some changes to the base `Event` type, to include an `eligibility_types` property on all events we send into Amplitude.\r\n\r\n## OAuth events\r\n\r\nLooking at the event reports over the last 14 days of production data, the [`started sign in` event](https://github.com/cal-itp/benefits/blob/dev/benefits/oauth/analytics.py#L16) is missing the `eligibility_types` property in 100% of recorded events. [See report here](https://data.amplitude.com/compiler/Benefits/events/main/latest/started%20sign%20in).\r\n\r\n## Eligibility events\r\n\r\nWe're also seeing unexpected behavior with the `eligibility` events for `courtesy_card`: the `eligiblity_types` property is coming through with the `event_properties`, but not with `user_properties`, leading to blanks/`(none)` when plotting the events on user-based charts. \r\n\r\nFor example, this [user checked `courtesy_card` eligibility](https://analytics.amplitude.com/compiler/project/304110/search/amplitude_id%3D555656738955?collapsed=true&sessionHandle=YXoogID_YXoogIG_IFfuPiL_BKPu_2b6a1cea-210a-8693-6f25-38c5de0f39c3&eventId=b505e207-9ca1-11ed-967a-9bb610a8bd25) and we can see the value in the raw `event_properties` output, but not `user_properties`:\r\n\r\n```json\r\n{\r\n  \"amplitude_id\": 555656738955,\r\n  \"app\": 304110,\r\n  \"client_event_time\": \"2023-01-25 11:16:23.396000\",\r\n  \"client_upload_time\": \"2023-01-25 11:16:23.506000\",\r\n  \"data_type\": \"event\",\r\n  \"display_name\": \"started eligibility\",\r\n  \"event_id\": 664,\r\n  \"event_properties\": {\r\n    \"eligibility_types\": [\r\n      \"courtesy_card\"\r\n    ],\r\n    \"eligibility_verifier\": \"MST Courtesy Card Eligibility Server Verifier\",\r\n    \"path\": \"/eligibility/confirm\",\r\n    \"transit_agency\": \"Monterey-Salinas Transit\"\r\n  },\r\n  \"event_time\": \"2023-01-25 11:16:23.396000\",\r\n  \"event_type\": \"started eligibility\",\r\n  \"language\": \"English\",\r\n  \"library\": \"http/2.0\",\r\n  \"server_received_time\": \"2023-01-25 11:16:23.506000\",\r\n  \"server_upload_time\": \"2023-01-25 11:16:23.508000\",\r\n  \"session_id\": 1674645209603,\r\n  \"source_id\": null,\r\n  \"start_version\": \"2023.01.1\",\r\n  \"timeline_hidden\": false,\r\n  \"user_creation_time\": \"2023-01-25 11:13:29.606000\",\r\n  \"user_id\": \"35aabc7e-d98c-451d-95ec-e4033fcec987\",\r\n  \"user_properties\": {\r\n    \"eligibility_verifier\": \"MST Courtesy Card Eligibility Server Verifier\",\r\n    \"referrer\": \"https://benefits.calitp.org/eligibility/confirm\",\r\n    \"referring_domain\": \"benefits.calitp.org\",\r\n    \"transit_agency\": \"Monterey-Salinas Transit\",\r\n    \"user_agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36\"\r\n  },\r\n  \"uuid\": \"b505e207-9ca1-11ed-967a-9bb610a8bd25\",\r\n  \"version_name\": \"2023.01.1\"\r\n}\r\n```\r\n\r\nAnd the resulting user chart shows categorizes this event as `(none)`:\r\n\r\n<img width=\"680\" alt=\"image\" src=\"https://user-images.githubusercontent.com/1783439/215842237-10a52ea7-5bad-4fa2-ad08-004e01d1f174.png\">\r\n\n", "before_files": [{"content": "\"\"\"\nThe eligibility application: analytics implementation.\n\"\"\"\nfrom benefits.core import analytics as core\n\n\nclass EligibilityEvent(core.Event):\n    \"\"\"Base analytics event for eligibility verification.\"\"\"\n\n    def __init__(self, request, event_type, eligibility_types):\n        super().__init__(request, event_type)\n        # overwrite core.Event eligibility_types\n        self.update_event_properties(eligibility_types=eligibility_types)\n\n\nclass SelectedVerifierEvent(EligibilityEvent):\n    \"\"\"Analytics event representing the user selecting an eligibility verifier.\"\"\"\n\n    def __init__(self, request, eligibility_types):\n        super().__init__(request, \"selected eligibility verifier\", eligibility_types)\n\n\nclass StartedEligibilityEvent(EligibilityEvent):\n    \"\"\"Analytics event representing the beginning of an eligibility verification check.\"\"\"\n\n    def __init__(self, request, eligibility_types):\n        super().__init__(request, \"started eligibility\", eligibility_types)\n\n\nclass ReturnedEligibilityEvent(EligibilityEvent):\n    \"\"\"Analytics event representing the end of an eligibility verification check.\"\"\"\n\n    def __init__(self, request, eligibility_types, status, error=None):\n        super().__init__(request, \"returned eligibility\", eligibility_types)\n        status = str(status).lower()\n        if status in (\"error\", \"fail\", \"success\"):\n            self.update_event_properties(status=status, error=error)\n        if status == \"success\":\n            self.update_user_properties(eligibility_types=eligibility_types)\n\n\ndef selected_verifier(request, eligibility_types):\n    \"\"\"Send the \"selected eligibility verifier\" analytics event.\"\"\"\n    core.send_event(SelectedVerifierEvent(request, eligibility_types))\n\n\ndef started_eligibility(request, eligibility_types):\n    \"\"\"Send the \"started eligibility\" analytics event.\"\"\"\n    core.send_event(StartedEligibilityEvent(request, eligibility_types))\n\n\ndef returned_error(request, eligibility_types, error):\n    \"\"\"Send the \"returned eligibility\" analytics event with an error status.\"\"\"\n    core.send_event(ReturnedEligibilityEvent(request, eligibility_types, status=\"error\", error=error))\n\n\ndef returned_fail(request, eligibility_types):\n    \"\"\"Send the \"returned eligibility\" analytics event with a fail status.\"\"\"\n    core.send_event(ReturnedEligibilityEvent(request, eligibility_types, status=\"fail\"))\n\n\ndef returned_success(request, eligibility_types):\n    \"\"\"Send the \"returned eligibility\" analytics event with a success status.\"\"\"\n    core.send_event(ReturnedEligibilityEvent(request, eligibility_types, status=\"success\"))\n", "path": "benefits/eligibility/analytics.py"}], "after_files": [{"content": "\"\"\"\nThe eligibility application: analytics implementation.\n\"\"\"\nfrom benefits.core import analytics as core\n\n\nclass EligibilityEvent(core.Event):\n    \"\"\"Base analytics event for eligibility verification.\"\"\"\n\n    def __init__(self, request, event_type, eligibility_types):\n        super().__init__(request, event_type)\n        # overwrite core.Event eligibility_types\n        self.update_event_properties(eligibility_types=eligibility_types)\n        self.update_user_properties(eligibility_types=eligibility_types)\n\n\nclass SelectedVerifierEvent(EligibilityEvent):\n    \"\"\"Analytics event representing the user selecting an eligibility verifier.\"\"\"\n\n    def __init__(self, request, eligibility_types):\n        super().__init__(request, \"selected eligibility verifier\", eligibility_types)\n\n\nclass StartedEligibilityEvent(EligibilityEvent):\n    \"\"\"Analytics event representing the beginning of an eligibility verification check.\"\"\"\n\n    def __init__(self, request, eligibility_types):\n        super().__init__(request, \"started eligibility\", eligibility_types)\n\n\nclass ReturnedEligibilityEvent(EligibilityEvent):\n    \"\"\"Analytics event representing the end of an eligibility verification check.\"\"\"\n\n    def __init__(self, request, eligibility_types, status, error=None):\n        super().__init__(request, \"returned eligibility\", eligibility_types)\n        status = str(status).lower()\n        if status in (\"error\", \"fail\", \"success\"):\n            self.update_event_properties(status=status, error=error)\n        if status == \"success\":\n            self.update_user_properties(eligibility_types=eligibility_types)\n\n\ndef selected_verifier(request, eligibility_types):\n    \"\"\"Send the \"selected eligibility verifier\" analytics event.\"\"\"\n    core.send_event(SelectedVerifierEvent(request, eligibility_types))\n\n\ndef started_eligibility(request, eligibility_types):\n    \"\"\"Send the \"started eligibility\" analytics event.\"\"\"\n    core.send_event(StartedEligibilityEvent(request, eligibility_types))\n\n\ndef returned_error(request, eligibility_types, error):\n    \"\"\"Send the \"returned eligibility\" analytics event with an error status.\"\"\"\n    core.send_event(ReturnedEligibilityEvent(request, eligibility_types, status=\"error\", error=error))\n\n\ndef returned_fail(request, eligibility_types):\n    \"\"\"Send the \"returned eligibility\" analytics event with a fail status.\"\"\"\n    core.send_event(ReturnedEligibilityEvent(request, eligibility_types, status=\"fail\"))\n\n\ndef returned_success(request, eligibility_types):\n    \"\"\"Send the \"returned eligibility\" analytics event with a success status.\"\"\"\n    core.send_event(ReturnedEligibilityEvent(request, eligibility_types, status=\"success\"))\n", "path": "benefits/eligibility/analytics.py"}]}