prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Dynamic challenges do not show a Next Challenge
  <!--
  If this is a bug report please fill out the template below.
  
  If this is a feature request please describe the behavior that you'd like to see.
  -->
  
  **Environment**:
  
  - CTFd Version/Commit: 3.6.0/8ead306f8b57c059192cd8b137f37ee41a078a41
  - Operating System: All
  - Web Browser and Version: All
  
  **What happened?**
  
  TLDR: *dynamic* challenges do not serve `next_id` to the frontend.
  
  **How to reproduce your issue**
  
  1. I created two challenges A and B with dynamic scoring.
  2. I opened the admin configuration for challenge A.
  3. I clicked "Next"
  4. I selected challenge B from the dropdown.
  5. I clicked the "Save" button.
  6. The input field is empty.
  
  **What did you expect to happen?**
  
  The input field shows "Challenge B".
  
  **Any associated stack traces or error logs**
  
  The issue arises from the lack of `next_id` field in API responses for dynamic challenges [here](https://github.com/CTFd/CTFd/blob/8ead306f8b57c059192cd8b137f37ee41a078a41/CTFd/plugins/dynamic_challenges/__init__.py#L60-L89).
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `CTFd/plugins/dynamic_challenges/__init__.py`
  Content:
  ```
  1 from flask import Blueprint
  2 
  3 from CTFd.models import Challenges, db
  4 from CTFd.plugins import register_plugin_assets_directory
  5 from CTFd.plugins.challenges import CHALLENGE_CLASSES, BaseChallenge
  6 from CTFd.plugins.dynamic_challenges.decay import DECAY_FUNCTIONS, logarithmic
  7 from CTFd.plugins.migrations import upgrade
  8 
  9 
  10 class DynamicChallenge(Challenges):
  11     __mapper_args__ = {"polymorphic_identity": "dynamic"}
  12     id = db.Column(
  13         db.Integer, db.ForeignKey("challenges.id", ondelete="CASCADE"), primary_key=True
  14     )
  15     initial = db.Column(db.Integer, default=0)
  16     minimum = db.Column(db.Integer, default=0)
  17     decay = db.Column(db.Integer, default=0)
  18     function = db.Column(db.String(32), default="logarithmic")
  19 
  20     def __init__(self, *args, **kwargs):
  21         super(DynamicChallenge, self).__init__(**kwargs)
  22         self.value = kwargs["initial"]
  23 
  24 
  25 class DynamicValueChallenge(BaseChallenge):
  26     id = "dynamic"  # Unique identifier used to register challenges
  27     name = "dynamic"  # Name of a challenge type
  28     templates = (
  29         {  # Handlebars templates used for each aspect of challenge editing & viewing
  30             "create": "/plugins/dynamic_challenges/assets/create.html",
  31             "update": "/plugins/dynamic_challenges/assets/update.html",
  32             "view": "/plugins/dynamic_challenges/assets/view.html",
  33         }
  34     )
  35     scripts = {  # Scripts that are loaded when a template is loaded
  36         "create": "/plugins/dynamic_challenges/assets/create.js",
  37         "update": "/plugins/dynamic_challenges/assets/update.js",
  38         "view": "/plugins/dynamic_challenges/assets/view.js",
  39     }
  40     # Route at which files are accessible. This must be registered using register_plugin_assets_directory()
  41     route = "/plugins/dynamic_challenges/assets/"
  42     # Blueprint used to access the static_folder directory.
  43     blueprint = Blueprint(
  44         "dynamic_challenges",
  45         __name__,
  46         template_folder="templates",
  47         static_folder="assets",
  48     )
  49     challenge_model = DynamicChallenge
  50 
  51     @classmethod
  52     def calculate_value(cls, challenge):
  53         f = DECAY_FUNCTIONS.get(challenge.function, logarithmic)
  54         value = f(challenge)
  55 
  56         challenge.value = value
  57         db.session.commit()
  58         return challenge
  59 
  60     @classmethod
  61     def read(cls, challenge):
  62         """
  63         This method is in used to access the data of a challenge in a format processable by the front end.
  64 
  65         :param challenge:
  66         :return: Challenge object, data dictionary to be returned to the user
  67         """
  68         challenge = DynamicChallenge.query.filter_by(id=challenge.id).first()
  69         data = {
  70             "id": challenge.id,
  71             "name": challenge.name,
  72             "value": challenge.value,
  73             "initial": challenge.initial,
  74             "decay": challenge.decay,
  75             "minimum": challenge.minimum,
  76             "description": challenge.description,
  77             "connection_info": challenge.connection_info,
  78             "category": challenge.category,
  79             "state": challenge.state,
  80             "max_attempts": challenge.max_attempts,
  81             "type": challenge.type,
  82             "type_data": {
  83                 "id": cls.id,
  84                 "name": cls.name,
  85                 "templates": cls.templates,
  86                 "scripts": cls.scripts,
  87             },
  88         }
  89         return data
  90 
  91     @classmethod
  92     def update(cls, challenge, request):
  93         """
  94         This method is used to update the information associated with a challenge. This should be kept strictly to the
  95         Challenges table and any child tables.
  96 
  97         :param challenge:
  98         :param request:
  99         :return:
  100         """
  101         data = request.form or request.get_json()
  102 
  103         for attr, value in data.items():
  104             # We need to set these to floats so that the next operations don't operate on strings
  105             if attr in ("initial", "minimum", "decay"):
  106                 value = float(value)
  107             setattr(challenge, attr, value)
  108 
  109         return DynamicValueChallenge.calculate_value(challenge)
  110 
  111     @classmethod
  112     def solve(cls, user, team, challenge, request):
  113         super().solve(user, team, challenge, request)
  114 
  115         DynamicValueChallenge.calculate_value(challenge)
  116 
  117 
  118 def load(app):
  119     upgrade(plugin_name="dynamic_challenges")
  120     CHALLENGE_CLASSES["dynamic"] = DynamicValueChallenge
  121     register_plugin_assets_directory(
  122         app, base_path="/plugins/dynamic_challenges/assets/"
  123     )
  124
  ```
  --- 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/CTFd/plugins/dynamic_challenges/__init__.py b/CTFd/plugins/dynamic_challenges/__init__.py
  --- a/CTFd/plugins/dynamic_challenges/__init__.py
  +++ b/CTFd/plugins/dynamic_challenges/__init__.py
  @@ -75,6 +75,7 @@
               "minimum": challenge.minimum,
               "description": challenge.description,
               "connection_info": challenge.connection_info,
  +            "next_id": challenge.next_id,
               "category": challenge.category,
               "state": challenge.state,
               "max_attempts": challenge.max_attempts,
  
verification_info: {"golden_diff": "diff --git a/CTFd/plugins/dynamic_challenges/__init__.py b/CTFd/plugins/dynamic_challenges/__init__.py\n--- a/CTFd/plugins/dynamic_challenges/__init__.py\n+++ b/CTFd/plugins/dynamic_challenges/__init__.py\n@@ -75,6 +75,7 @@\n             \"minimum\": challenge.minimum,\n             \"description\": challenge.description,\n             \"connection_info\": challenge.connection_info,\n+            \"next_id\": challenge.next_id,\n             \"category\": challenge.category,\n             \"state\": challenge.state,\n             \"max_attempts\": challenge.max_attempts,\n", "issue": "Dynamic challenges do not show a Next Challenge\n<!--\r\nIf this is a bug report please fill out the template below.\r\n\r\nIf this is a feature request please describe the behavior that you'd like to see.\r\n-->\r\n\r\n**Environment**:\r\n\r\n- CTFd Version/Commit: 3.6.0/8ead306f8b57c059192cd8b137f37ee41a078a41\r\n- Operating System: All\r\n- Web Browser and Version: All\r\n\r\n**What happened?**\r\n\r\nTLDR: *dynamic* challenges do not serve `next_id` to the frontend.\r\n\r\n**How to reproduce your issue**\r\n\r\n1. I created two challenges A and B with dynamic scoring.\r\n2. I opened the admin configuration for challenge A.\r\n3. I clicked \"Next\"\r\n4. I selected challenge B from the dropdown.\r\n5. I clicked the \"Save\" button.\r\n6. The input field is empty.\r\n\r\n**What did you expect to happen?**\r\n\r\nThe input field shows \"Challenge B\".\r\n\r\n**Any associated stack traces or error logs**\r\n\r\nThe issue arises from the lack of `next_id` field in API responses for dynamic challenges [here](https://github.com/CTFd/CTFd/blob/8ead306f8b57c059192cd8b137f37ee41a078a41/CTFd/plugins/dynamic_challenges/__init__.py#L60-L89).\r\n\n", "before_files": [{"content": "from flask import Blueprint\n\nfrom CTFd.models import Challenges, db\nfrom CTFd.plugins import register_plugin_assets_directory\nfrom CTFd.plugins.challenges import CHALLENGE_CLASSES, BaseChallenge\nfrom CTFd.plugins.dynamic_challenges.decay import DECAY_FUNCTIONS, logarithmic\nfrom CTFd.plugins.migrations import upgrade\n\n\nclass DynamicChallenge(Challenges):\n    __mapper_args__ = {\"polymorphic_identity\": \"dynamic\"}\n    id = db.Column(\n        db.Integer, db.ForeignKey(\"challenges.id\", ondelete=\"CASCADE\"), primary_key=True\n    )\n    initial = db.Column(db.Integer, default=0)\n    minimum = db.Column(db.Integer, default=0)\n    decay = db.Column(db.Integer, default=0)\n    function = db.Column(db.String(32), default=\"logarithmic\")\n\n    def __init__(self, *args, **kwargs):\n        super(DynamicChallenge, self).__init__(**kwargs)\n        self.value = kwargs[\"initial\"]\n\n\nclass DynamicValueChallenge(BaseChallenge):\n    id = \"dynamic\"  # Unique identifier used to register challenges\n    name = \"dynamic\"  # Name of a challenge type\n    templates = (\n        {  # Handlebars templates used for each aspect of challenge editing & viewing\n            \"create\": \"/plugins/dynamic_challenges/assets/create.html\",\n            \"update\": \"/plugins/dynamic_challenges/assets/update.html\",\n            \"view\": \"/plugins/dynamic_challenges/assets/view.html\",\n        }\n    )\n    scripts = {  # Scripts that are loaded when a template is loaded\n        \"create\": \"/plugins/dynamic_challenges/assets/create.js\",\n        \"update\": \"/plugins/dynamic_challenges/assets/update.js\",\n        \"view\": \"/plugins/dynamic_challenges/assets/view.js\",\n    }\n    # Route at which files are accessible. This must be registered using register_plugin_assets_directory()\n    route = \"/plugins/dynamic_challenges/assets/\"\n    # Blueprint used to access the static_folder directory.\n    blueprint = Blueprint(\n        \"dynamic_challenges\",\n        __name__,\n        template_folder=\"templates\",\n        static_folder=\"assets\",\n    )\n    challenge_model = DynamicChallenge\n\n    @classmethod\n    def calculate_value(cls, challenge):\n        f = DECAY_FUNCTIONS.get(challenge.function, logarithmic)\n        value = f(challenge)\n\n        challenge.value = value\n        db.session.commit()\n        return challenge\n\n    @classmethod\n    def read(cls, challenge):\n        \"\"\"\n        This method is in used to access the data of a challenge in a format processable by the front end.\n\n        :param challenge:\n        :return: Challenge object, data dictionary to be returned to the user\n        \"\"\"\n        challenge = DynamicChallenge.query.filter_by(id=challenge.id).first()\n        data = {\n            \"id\": challenge.id,\n            \"name\": challenge.name,\n            \"value\": challenge.value,\n            \"initial\": challenge.initial,\n            \"decay\": challenge.decay,\n            \"minimum\": challenge.minimum,\n            \"description\": challenge.description,\n            \"connection_info\": challenge.connection_info,\n            \"category\": challenge.category,\n            \"state\": challenge.state,\n            \"max_attempts\": challenge.max_attempts,\n            \"type\": challenge.type,\n            \"type_data\": {\n                \"id\": cls.id,\n                \"name\": cls.name,\n                \"templates\": cls.templates,\n                \"scripts\": cls.scripts,\n            },\n        }\n        return data\n\n    @classmethod\n    def update(cls, challenge, request):\n        \"\"\"\n        This method is used to update the information associated with a challenge. This should be kept strictly to the\n        Challenges table and any child tables.\n\n        :param challenge:\n        :param request:\n        :return:\n        \"\"\"\n        data = request.form or request.get_json()\n\n        for attr, value in data.items():\n            # We need to set these to floats so that the next operations don't operate on strings\n            if attr in (\"initial\", \"minimum\", \"decay\"):\n                value = float(value)\n            setattr(challenge, attr, value)\n\n        return DynamicValueChallenge.calculate_value(challenge)\n\n    @classmethod\n    def solve(cls, user, team, challenge, request):\n        super().solve(user, team, challenge, request)\n\n        DynamicValueChallenge.calculate_value(challenge)\n\n\ndef load(app):\n    upgrade(plugin_name=\"dynamic_challenges\")\n    CHALLENGE_CLASSES[\"dynamic\"] = DynamicValueChallenge\n    register_plugin_assets_directory(\n        app, base_path=\"/plugins/dynamic_challenges/assets/\"\n    )\n", "path": "CTFd/plugins/dynamic_challenges/__init__.py"}], "after_files": [{"content": "from flask import Blueprint\n\nfrom CTFd.models import Challenges, db\nfrom CTFd.plugins import register_plugin_assets_directory\nfrom CTFd.plugins.challenges import CHALLENGE_CLASSES, BaseChallenge\nfrom CTFd.plugins.dynamic_challenges.decay import DECAY_FUNCTIONS, logarithmic\nfrom CTFd.plugins.migrations import upgrade\n\n\nclass DynamicChallenge(Challenges):\n    __mapper_args__ = {\"polymorphic_identity\": \"dynamic\"}\n    id = db.Column(\n        db.Integer, db.ForeignKey(\"challenges.id\", ondelete=\"CASCADE\"), primary_key=True\n    )\n    initial = db.Column(db.Integer, default=0)\n    minimum = db.Column(db.Integer, default=0)\n    decay = db.Column(db.Integer, default=0)\n    function = db.Column(db.String(32), default=\"logarithmic\")\n\n    def __init__(self, *args, **kwargs):\n        super(DynamicChallenge, self).__init__(**kwargs)\n        self.value = kwargs[\"initial\"]\n\n\nclass DynamicValueChallenge(BaseChallenge):\n    id = \"dynamic\"  # Unique identifier used to register challenges\n    name = \"dynamic\"  # Name of a challenge type\n    templates = (\n        {  # Handlebars templates used for each aspect of challenge editing & viewing\n            \"create\": \"/plugins/dynamic_challenges/assets/create.html\",\n            \"update\": \"/plugins/dynamic_challenges/assets/update.html\",\n            \"view\": \"/plugins/dynamic_challenges/assets/view.html\",\n        }\n    )\n    scripts = {  # Scripts that are loaded when a template is loaded\n        \"create\": \"/plugins/dynamic_challenges/assets/create.js\",\n        \"update\": \"/plugins/dynamic_challenges/assets/update.js\",\n        \"view\": \"/plugins/dynamic_challenges/assets/view.js\",\n    }\n    # Route at which files are accessible. This must be registered using register_plugin_assets_directory()\n    route = \"/plugins/dynamic_challenges/assets/\"\n    # Blueprint used to access the static_folder directory.\n    blueprint = Blueprint(\n        \"dynamic_challenges\",\n        __name__,\n        template_folder=\"templates\",\n        static_folder=\"assets\",\n    )\n    challenge_model = DynamicChallenge\n\n    @classmethod\n    def calculate_value(cls, challenge):\n        f = DECAY_FUNCTIONS.get(challenge.function, logarithmic)\n        value = f(challenge)\n\n        challenge.value = value\n        db.session.commit()\n        return challenge\n\n    @classmethod\n    def read(cls, challenge):\n        \"\"\"\n        This method is in used to access the data of a challenge in a format processable by the front end.\n\n        :param challenge:\n        :return: Challenge object, data dictionary to be returned to the user\n        \"\"\"\n        challenge = DynamicChallenge.query.filter_by(id=challenge.id).first()\n        data = {\n            \"id\": challenge.id,\n            \"name\": challenge.name,\n            \"value\": challenge.value,\n            \"initial\": challenge.initial,\n            \"decay\": challenge.decay,\n            \"minimum\": challenge.minimum,\n            \"description\": challenge.description,\n            \"connection_info\": challenge.connection_info,\n            \"next_id\": challenge.next_id,\n            \"category\": challenge.category,\n            \"state\": challenge.state,\n            \"max_attempts\": challenge.max_attempts,\n            \"type\": challenge.type,\n            \"type_data\": {\n                \"id\": cls.id,\n                \"name\": cls.name,\n                \"templates\": cls.templates,\n                \"scripts\": cls.scripts,\n            },\n        }\n        return data\n\n    @classmethod\n    def update(cls, challenge, request):\n        \"\"\"\n        This method is used to update the information associated with a challenge. This should be kept strictly to the\n        Challenges table and any child tables.\n\n        :param challenge:\n        :param request:\n        :return:\n        \"\"\"\n        data = request.form or request.get_json()\n\n        for attr, value in data.items():\n            # We need to set these to floats so that the next operations don't operate on strings\n            if attr in (\"initial\", \"minimum\", \"decay\"):\n                value = float(value)\n            setattr(challenge, attr, value)\n\n        return DynamicValueChallenge.calculate_value(challenge)\n\n    @classmethod\n    def solve(cls, user, team, challenge, request):\n        super().solve(user, team, challenge, request)\n\n        DynamicValueChallenge.calculate_value(challenge)\n\n\ndef load(app):\n    upgrade(plugin_name=\"dynamic_challenges\")\n    CHALLENGE_CLASSES[\"dynamic\"] = DynamicValueChallenge\n    register_plugin_assets_directory(\n        app, base_path=\"/plugins/dynamic_challenges/assets/\"\n    )\n", "path": "CTFd/plugins/dynamic_challenges/__init__.py"}]}