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()

```

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,

{"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"}]}