meal-order-manager/src/server/app.py
Adam Moussa 440117c9a1
Fix ruff lint and format violations, update README (#5)
Apply ruff check --fix and ruff format across all Python files to
pass CI pipeline. Remove unused imports (os, sys), fix f-strings
without placeholders. Update README to reflect sync-roster Lambda,
corrected shared layer path, and current project structure.
2026-05-12 19:31:27 -04:00

129 lines
3.5 KiB
Python

"""
Lightweight Flask server for the meal order form.
Serves the generated HTML form and handles order submissions.
Orders are saved as JSON files in the orders directory, one per employee per week.
"""
import json
from datetime import datetime
from pathlib import Path
from flask import Flask, jsonify, request, send_file
PROJECT_ROOT = Path(__file__).resolve().parents[2]
CONFIG_PATH = PROJECT_ROOT / "config.json"
OUTPUT_DIR = PROJECT_ROOT / "output"
ORDERS_DIR = PROJECT_ROOT / "orders"
app = Flask(__name__)
def load_config():
with open(CONFIG_PATH) as f:
return json.load(f)
def current_week() -> str:
return datetime.now().strftime("%Y-W%U")
def latest_menu_file() -> Path | None:
files = sorted(OUTPUT_DIR.glob("menu-*.json"), reverse=True)
return files[0] if files else None
@app.route("/")
def index():
form_file = OUTPUT_DIR / f"order-form-{current_week()}.html"
if not form_file.exists():
return "No order form generated for this week. Run generate_form.py first.", 404
return send_file(form_file)
@app.route("/api/menu")
def get_menu():
menu_file = latest_menu_file()
if not menu_file:
return jsonify(
{"error": "No menu data available. Run scrape_menu.py first."}
), 404
with open(menu_file) as f:
return jsonify(json.load(f))
@app.route("/api/roster")
def get_roster():
config = load_config()
return jsonify(config.get("roster", []))
@app.route("/api/submit-order", methods=["POST"])
def submit_order():
data = request.get_json()
if not data:
return jsonify({"error": "No data received"}), 400
name = data.get("employee_name", "").strip()
email = data.get("employee_email", "").strip()
items = data.get("items", [])
if not name:
return jsonify({"error": "Employee name is required"}), 400
if not email:
return jsonify({"error": "Employee email is required"}), 400
if not items or not any(i.get("quantity", 0) > 0 for i in items):
return jsonify({"error": "Please select at least one meal"}), 400
week = current_week()
week_dir = ORDERS_DIR / week
week_dir.mkdir(parents=True, exist_ok=True)
safe_name = (
"".join(c if c.isalnum() or c in "-_ " else "" for c in name)
.strip()
.replace(" ", "-")
.lower()
)
order_file = week_dir / f"{safe_name}.json"
order = {
"employee_name": name,
"employee_email": email,
"week": week,
"submitted_at": datetime.now().isoformat(),
"items": [i for i in items if i.get("quantity", 0) > 0],
"total": sum(
(i.get("price", 0) or 0) * i.get("quantity", 0)
for i in items
if i.get("quantity", 0) > 0
),
}
with open(order_file, "w") as f:
json.dump(order, f, indent=2)
return jsonify(
{"status": "ok", "message": f"Order saved for {name}", "total": order["total"]}
)
@app.route("/api/orders/<week>")
def get_orders(week: str):
week_dir = ORDERS_DIR / week
if not week_dir.exists():
return jsonify({"orders": [], "week": week})
orders = []
for f in sorted(week_dir.glob("*.json")):
with open(f) as fh:
orders.append(json.load(fh))
return jsonify({"orders": orders, "week": week})
if __name__ == "__main__":
ORDERS_DIR.mkdir(exist_ok=True)
print(f"Menu file: {latest_menu_file()}")
print(f"Orders dir: {ORDERS_DIR}")
app.run(host="0.0.0.0", port=5050, debug=True)