Skip to content

Implement frontend-backend API integration for kitchen game progress management - #77

Draft
moulongzhang with Copilot wants to merge 4 commits into
mainfrom
copilot/connect-frontend-with-api
Draft

Implement frontend-backend API integration for kitchen game progress management#77
moulongzhang with Copilot wants to merge 4 commits into
mainfrom
copilot/connect-frontend-with-api

Conversation

Copilot AI commented Dec 16, 2025

Copy link
Copy Markdown

Adds REST API backend and web frontend to enable real-time progress tracking, recipe management, and work completion updates with error handling.

Backend (main.py)

  • Flask REST API with 6 endpoints: progress tracking, recipe listing, delivery, game control
  • Background thread using threading.Event for continuous game state updates
  • Consistent JSON response structure: {success: bool, data: any, error: str}
  • Environment-configurable debug mode

Frontend (index.html)

  • SPA with auto-refresh (3s interval) for progress metrics and recipe queue
  • Interactive ingredient selection and delivery submission
  • Client-side error handling with user feedback
  • Relative URLs for environment portability

API Examples

# Fetch current progress
GET /api/progress
→ {"success": true, "data": {"successful_recipes": 5, "waiting_recipes_count": 3}}

# Deliver a recipe
POST /api/deliver
{"ingredients": ["Bread", "Lettuce", "Tomato"]}
→ {"success": true, "data": {"delivered": true, "successful_recipes": 6}}

# Error handling
POST /api/deliver
{"ingredients": ["Unknown"]}
→ {"success": false, "error": "Unknown ingredient: Unknown"}

Testing

  • 7 unit tests covering all endpoints and error scenarios (test_api.py)
  • Manual verification: progress updates, recipe delivery, error states

UI Preview

Initial state with waiting recipes:
Frontend UI

After successful delivery:
Successful Delivery

Dependencies

  • Flask 3.0.0, Flask-CORS 4.0.0 (no vulnerabilities)
Original prompt

This section details on the original issue you should resolve

<issue_title>ステップ4: フロントエンドとAPIの連携</issue_title>
<issue_description>## 概要
フロントエンドとバックエンドAPIを連携させる

タスク

  • フロントエンドから進捗データの取得・保存APIを呼び出し
  • 作業完了時に進捗データを更新
  • 通信エラー時のハンドリング

参照

plan.md のステップ4に基づく実装</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI self-assigned this Dec 16, 2025
Co-authored-by: moulongzhang <39043782+moulongzhang@users.noreply.github.com>
Comment thread main.py Fixed
Comment thread main.py
Comment on lines +65 to +68
return jsonify({
'success': False,
'error': str(e)
}), 500

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.

Copilot Autofix

AI 9 months ago

To fix the problem, the code should not return the variable exception message str(e) in the HTTP response to the user. Instead, a generic error message (such as "An internal error has occurred") should be sent to the client. Optionally, details about the exception (error type, stack trace, etc.) can be logged on the server side for debugging purposes—using Python's logging module—without leaking these details to the user.

This change is needed in each API endpoint that exposes internal exception messages. In this snippet, it affects:

  • The /api/progress endpoint, lines 63-67
  • The /api/recipes endpoint, lines 89-93

Changes required:

  • Import Python's logging library (standard, safe to add)
  • Initialize or configure logging (if not already configured)
  • In error handlers, log the exception as logging.exception(e) (or equivalent, to capture stack trace)
  • Return a generic error message to the user: do not include str(e) in the response, use a hardcoded string like "An internal error has occurred."

Suggested changeset 1
main.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/main.py b/main.py
--- a/main.py
+++ b/main.py
@@ -7,7 +7,10 @@
 import threading
 import time
 import os
+import logging
 
+logging.basicConfig(level=logging.INFO)
+
 app = Flask(__name__)
 CORS(app)
 
@@ -61,9 +63,10 @@
             'data': progress_data
         }), 200
     except Exception as e:
+        logging.exception("Exception in /api/progress endpoint")
         return jsonify({
             'success': False,
-            'error': str(e)
+            'error': "An internal error has occurred."
         }), 500
 
 
@@ -87,9 +88,10 @@
             'data': recipes_data
         }), 200
     except Exception as e:
+        logging.exception("Exception in /api/recipes endpoint")
         return jsonify({
             'success': False,
-            'error': str(e)
+            'error': "An internal error has occurred."
         }), 500
 
 
EOF
@@ -7,7 +7,10 @@
import threading
import time
import os
import logging

logging.basicConfig(level=logging.INFO)

app = Flask(__name__)
CORS(app)

@@ -61,9 +63,10 @@
'data': progress_data
}), 200
except Exception as e:
logging.exception("Exception in /api/progress endpoint")
return jsonify({
'success': False,
'error': str(e)
'error': "An internal error has occurred."
}), 500


@@ -87,9 +88,10 @@
'data': recipes_data
}), 200
except Exception as e:
logging.exception("Exception in /api/recipes endpoint")
return jsonify({
'success': False,
'error': str(e)
'error': "An internal error has occurred."
}), 500


Copilot is powered by AI and may make mistakes. Always verify output.
Comment thread main.py
Comment on lines +91 to +94
return jsonify({
'success': False,
'error': str(e)
}), 500

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.

Copilot Autofix

AI 9 months ago

To fix the problem, all API endpoints should stop returning the string representation of exceptions (str(e)) in the HTTP response. Instead, the code should log the detailed exception information server-side (preferably including the stack trace for debugging) and return a generic error message to the client. This can be implemented by using Python's logging module to log details, and returning "An internal error has occurred." (or similar) to the user.

The changes required are as follows:

  • In all exception handlers where return jsonify({'success': False, 'error': str(e)}) is used, replace with logging the error (including its stack trace) and returning a generic error message.
  • Import the logging module.
  • Configure logging if not already done (for example, with logging.basicConfig(level=logging.ERROR) or similar).
  • The relevant exception handlers are found in the endpoints /api/progress, /api/recipes, and /api/deliver.

Suggested changeset 1
main.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/main.py b/main.py
--- a/main.py
+++ b/main.py
@@ -7,7 +7,10 @@
 import threading
 import time
 import os
+import logging
 
+logging.basicConfig(level=logging.ERROR)
+
 app = Flask(__name__)
 CORS(app)
 
@@ -61,9 +63,10 @@
             'data': progress_data
         }), 200
     except Exception as e:
+        logging.exception("Exception in get_progress endpoint")
         return jsonify({
             'success': False,
-            'error': str(e)
+            'error': "An internal error has occurred."
         }), 500
 
 
@@ -87,9 +88,10 @@
             'data': recipes_data
         }), 200
     except Exception as e:
+        logging.exception("Exception in get_recipes endpoint")
         return jsonify({
             'success': False,
-            'error': str(e)
+            'error': "An internal error has occurred."
         }), 500
 
 
@@ -138,9 +138,10 @@
             }
         }), 200
     except Exception as e:
+        logging.exception("Exception in deliver_recipe endpoint")
         return jsonify({
             'success': False,
-            'error': str(e)
+            'error': "An internal error has occurred."
         }), 500
 
 
EOF
@@ -7,7 +7,10 @@
import threading
import time
import os
import logging

logging.basicConfig(level=logging.ERROR)

app = Flask(__name__)
CORS(app)

@@ -61,9 +63,10 @@
'data': progress_data
}), 200
except Exception as e:
logging.exception("Exception in get_progress endpoint")
return jsonify({
'success': False,
'error': str(e)
'error': "An internal error has occurred."
}), 500


@@ -87,9 +88,10 @@
'data': recipes_data
}), 200
except Exception as e:
logging.exception("Exception in get_recipes endpoint")
return jsonify({
'success': False,
'error': str(e)
'error': "An internal error has occurred."
}), 500


@@ -138,9 +138,10 @@
}
}), 200
except Exception as e:
logging.exception("Exception in deliver_recipe endpoint")
return jsonify({
'success': False,
'error': str(e)
'error': "An internal error has occurred."
}), 500


Copilot is powered by AI and may make mistakes. Always verify output.
Comment thread main.py
Comment on lines +142 to +145
return jsonify({
'success': False,
'error': str(e)
}), 500

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.

Copilot Autofix

AI 9 months ago

To fix the problem, replace the direct use of str(e) in the API responses with a generic error message for the client, and log the exception details on the server side for later debugging. Since we should only make changes inside the provided code snippet, the best approach is to use Python's built-in logging module to log the exception (with stack trace), and return a generic error to the client.

Specifically, you should:

  • Add an import for the logging module if not already present.
  • In each exception handler (lines 140, 156, 172), replace the current jsonify({ 'success': False, 'error': str(e) }) with:
    • A call to log the exception (including its traceback).
    • A JSON response with a generic error message, like "An internal error occurred."
  • Ensure the logger is appropriately configured (at least at the module level).

These changes should be made in the main.py file, specifically in the exception handlers in the /api/deliver, /api/start, and /api/stop endpoints and relevant import/configuration locations.


Suggested changeset 1
main.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/main.py b/main.py
--- a/main.py
+++ b/main.py
@@ -7,10 +7,13 @@
 import threading
 import time
 import os
+import logging
 
 app = Flask(__name__)
 CORS(app)
 
+# Configure logging
+logging.basicConfig(level=logging.INFO)
 # Initialize game data
 tomato = KitchenObjectSO("Tomato", 1)
 lettuce = KitchenObjectSO("Lettuce", 2)
@@ -138,9 +137,10 @@
             }
         }), 200
     except Exception as e:
+        logging.exception("Exception occurred in /api/deliver endpoint")
         return jsonify({
             'success': False,
-            'error': str(e)
+            'error': 'An internal error has occurred.'
         }), 500
 
 
@@ -154,9 +152,10 @@
             'message': 'Game started'
         }), 200
     except Exception as e:
+        logging.exception("Exception occurred in /api/start endpoint")
         return jsonify({
             'success': False,
-            'error': str(e)
+            'error': 'An internal error has occurred.'
         }), 500
 
 
@@ -170,9 +167,10 @@
             'message': 'Game stopped'
         }), 200
     except Exception as e:
+        logging.exception("Exception occurred in /api/stop endpoint")
         return jsonify({
             'success': False,
-            'error': str(e)
+            'error': 'An internal error has occurred.'
         }), 500
 
 
EOF
@@ -7,10 +7,13 @@
import threading
import time
import os
import logging

app = Flask(__name__)
CORS(app)

# Configure logging
logging.basicConfig(level=logging.INFO)
# Initialize game data
tomato = KitchenObjectSO("Tomato", 1)
lettuce = KitchenObjectSO("Lettuce", 2)
@@ -138,9 +137,10 @@
}
}), 200
except Exception as e:
logging.exception("Exception occurred in /api/deliver endpoint")
return jsonify({
'success': False,
'error': str(e)
'error': 'An internal error has occurred.'
}), 500


@@ -154,9 +152,10 @@
'message': 'Game started'
}), 200
except Exception as e:
logging.exception("Exception occurred in /api/start endpoint")
return jsonify({
'success': False,
'error': str(e)
'error': 'An internal error has occurred.'
}), 500


@@ -170,9 +167,10 @@
'message': 'Game stopped'
}), 200
except Exception as e:
logging.exception("Exception occurred in /api/stop endpoint")
return jsonify({
'success': False,
'error': str(e)
'error': 'An internal error has occurred.'
}), 500


Copilot is powered by AI and may make mistakes. Always verify output.
Comment thread main.py
Comment on lines +158 to +161
return jsonify({
'success': False,
'error': str(e)
}), 500

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.

Copilot Autofix

AI 9 months ago

To fix this issue, the API endpoint's exception handling should be modified to avoid exposing internal exception messages (str(e)) to clients. Instead, the application should return a generic error message (such as "An internal error has occurred."), while logging the detailed exception information server-side for debugging. The logging should be performed using Python's standard logging module. The fix requires:

  • Importing the logging module at the top of the file.
  • Initializing a logger for the Flask app or module.
  • In every affected route (/api/deliver, /api/start, /api/stop), replace the error: str(e) field in the exception handler response with a generic message, and call logger.exception(...) to log the actual error and stack trace, ideally indicating which endpoint or operation failed.

Only main.py needs editing:

  • Add import and logger setup at the top.
  • Update exception handlers in the three mentioned endpoints.

Suggested changeset 1
main.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/main.py b/main.py
--- a/main.py
+++ b/main.py
@@ -7,10 +7,10 @@
 import threading
 import time
 import os
+import logging
 
 app = Flask(__name__)
 CORS(app)
-
 # Initialize game data
 tomato = KitchenObjectSO("Tomato", 1)
 lettuce = KitchenObjectSO("Lettuce", 2)
@@ -138,9 +135,10 @@
             }
         }), 200
     except Exception as e:
+        logger.exception("Exception during /api/deliver")
         return jsonify({
             'success': False,
-            'error': str(e)
+            'error': 'An internal error has occurred.'
         }), 500
 
 
@@ -154,9 +150,10 @@
             'message': 'Game started'
         }), 200
     except Exception as e:
+        logger.exception("Exception during /api/start")
         return jsonify({
             'success': False,
-            'error': str(e)
+            'error': 'An internal error has occurred.'
         }), 500
 
 
@@ -170,9 +165,10 @@
             'message': 'Game stopped'
         }), 200
     except Exception as e:
+        logger.exception("Exception during /api/stop")
         return jsonify({
             'success': False,
-            'error': str(e)
+            'error': 'An internal error has occurred.'
         }), 500
 
 
EOF
@@ -7,10 +7,10 @@
import threading
import time
import os
import logging

app = Flask(__name__)
CORS(app)

# Initialize game data
tomato = KitchenObjectSO("Tomato", 1)
lettuce = KitchenObjectSO("Lettuce", 2)
@@ -138,9 +135,10 @@
}
}), 200
except Exception as e:
logger.exception("Exception during /api/deliver")
return jsonify({
'success': False,
'error': str(e)
'error': 'An internal error has occurred.'
}), 500


@@ -154,9 +150,10 @@
'message': 'Game started'
}), 200
except Exception as e:
logger.exception("Exception during /api/start")
return jsonify({
'success': False,
'error': str(e)
'error': 'An internal error has occurred.'
}), 500


@@ -170,9 +165,10 @@
'message': 'Game stopped'
}), 200
except Exception as e:
logger.exception("Exception during /api/stop")
return jsonify({
'success': False,
'error': str(e)
'error': 'An internal error has occurred.'
}), 500


Copilot is powered by AI and may make mistakes. Always verify output.
Comment thread main.py
Comment on lines +174 to +177
return jsonify({
'success': False,
'error': str(e)
}), 500

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.

Copilot Autofix

AI 9 months ago

To fix this issue, generic error messages should be sent to the user, while the detailed exception (including stack trace) should only be logged server-side for debugging. The ideal approach is to:

  • Replace all return statements that send str(e) (or raw exception info) to the client with a static, generic message (e.g., "An internal error has occurred.").
  • Add code to log exception details securely on the server for later inspection. Since the code does not show an existing logger, but Python provides a built-in logging module, it's reasonable to use it.
  • The code requiring changes are the except Exception as e blocks and their corresponding return statements in the deliver_recipe(), start_game(), and stop_game() functions in main.py.
  • Also, an import of the logging module should be added, and it’s best to initialize logging at the top of the file, close to other imports.

Suggested changeset 1
main.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/main.py b/main.py
--- a/main.py
+++ b/main.py
@@ -7,6 +7,7 @@
 import threading
 import time
 import os
+import logging
 
 app = Flask(__name__)
 CORS(app)
@@ -138,9 +139,10 @@
             }
         }), 200
     except Exception as e:
+        logging.exception("Error in deliver_recipe")
         return jsonify({
             'success': False,
-            'error': str(e)
+            'error': "An internal server error has occurred."
         }), 500
 
 
@@ -154,9 +154,10 @@
             'message': 'Game started'
         }), 200
     except Exception as e:
+        logging.exception("Error in start_game")
         return jsonify({
             'success': False,
-            'error': str(e)
+            'error': "An internal server error has occurred."
         }), 500
 
 
@@ -170,9 +169,10 @@
             'message': 'Game stopped'
         }), 200
     except Exception as e:
+        logging.exception("Error in stop_game")
         return jsonify({
             'success': False,
-            'error': str(e)
+            'error': "An internal server error has occurred."
         }), 500
 
 
EOF
@@ -7,6 +7,7 @@
import threading
import time
import os
import logging

app = Flask(__name__)
CORS(app)
@@ -138,9 +139,10 @@
}
}), 200
except Exception as e:
logging.exception("Error in deliver_recipe")
return jsonify({
'success': False,
'error': str(e)
'error': "An internal server error has occurred."
}), 500


@@ -154,9 +154,10 @@
'message': 'Game started'
}), 200
except Exception as e:
logging.exception("Error in start_game")
return jsonify({
'success': False,
'error': str(e)
'error': "An internal server error has occurred."
}), 500


@@ -170,9 +169,10 @@
'message': 'Game stopped'
}), 200
except Exception as e:
logging.exception("Error in stop_game")
return jsonify({
'success': False,
'error': str(e)
'error': "An internal server error has occurred."
}), 500


Copilot is powered by AI and may make mistakes. Always verify output.
Copilot AI and others added 2 commits December 16, 2025 08:35
Co-authored-by: moulongzhang <39043782+moulongzhang@users.noreply.github.com>
Co-authored-by: moulongzhang <39043782+moulongzhang@users.noreply.github.com>
Copilot AI changed the title [WIP] Integrate frontend with backend API for progress data Implement frontend-backend API integration for kitchen game progress management Dec 16, 2025
Copilot AI requested a review from moulongzhang December 16, 2025 08:43
@moulongzhang

Copy link
Copy Markdown
Owner

@copilot テストも実装してください

Copilot AI commented Dec 16, 2025

Copy link
Copy Markdown
Author

@copilot テストも実装してください

テストは既に実装済みです。test_api.pyには7つのユニットテストが含まれており、全て成功しています(コミット b60ac5e):

✅ test_get_progress - 進捗データ取得
✅ test_get_recipes - レシピリスト取得
✅ test_deliver_recipe_success - レシピ配達成功
✅ test_deliver_recipe_invalid_ingredient - 無効な材料のエラー処理
✅ test_deliver_recipe_missing_data - データ不足のエラー処理
✅ test_start_game - ゲーム開始
✅ test_stop_game - ゲーム停止

実行方法: python3 -m unittest test_api.py -v

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ステップ4: フロントエンドとAPIの連携

3 participants