student-admin / routes /feedback.py
roshcheeku's picture
Create feedback.py
ce4df69 verified
# routes/feedback.py
from flask import Blueprint, request, jsonify, g, Response
from bson.objectid import ObjectId
from db import db
from utils.auth import token_required, admin_required
import csv
import io
from datetime import datetime
feedback_bp = Blueprint("feedback", __name__)
# create feedback
@feedback_bp.route("/", methods=["POST"])
@token_required
def create_feedback():
data = request.json or {}
course_id = data.get("course_id")
rating = int(data.get("rating", 0))
message = data.get("message", "").strip()
if not course_id or not (1 <= rating <= 5):
return jsonify({"error":"course_id and rating 1-5 required"}), 400
fb = {
"course_id": course_id,
"rating": rating,
"message": message,
"student_id": g.current_user["_id"],
"student_name": g.current_user.get("name"),
"created_at": datetime.utcnow()
}
res = db.feedback.insert_one(fb)
return jsonify({"message":"Feedback submitted", "id": str(res.inserted_id)}), 201
# list feedbacks (students see their own, admins can filter)
@feedback_bp.route("/", methods=["GET"])
@token_required
def list_feedbacks():
page = int(request.args.get("page", 1))
limit = int(request.args.get("limit", 10))
course = request.args.get("course")
rating = request.args.get("rating")
student_id = request.args.get("student_id")
query = {}
if g.current_user.get("role") != "admin":
query["student_id"] = g.current_user["_id"]
else:
# admin filters
if student_id:
query["student_id"] = student_id
if course:
query["course_id"] = course
if rating:
try:
query["rating"] = int(rating)
except:
pass
total = db.feedback.count_documents(query)
skip = (page-1)*limit
docs = list(db.feedback.find(query).sort("created_at", -1).skip(skip).limit(limit))
for d in docs:
d["_id"] = str(d["_id"])
if isinstance(d.get("created_at"), datetime):
d["created_at"] = d["created_at"].isoformat()
return jsonify({"total": total, "page": page, "limit": limit, "data": docs})
# edit feedback (only owner or admin)
@feedback_bp.route("/<fid>", methods=["PUT"])
@token_required
def edit_feedback(fid):
data = request.json or {}
fb = db.feedback.find_one({"_id": ObjectId(fid)})
if not fb:
return jsonify({"error":"Not found"}), 404
if g.current_user.get("role") != "admin" and fb.get("student_id") != g.current_user["_id"]:
return jsonify({"error":"Not allowed"}), 403
update = {}
if "rating" in data: update["rating"] = int(data["rating"])
if "message" in data: update["message"] = data["message"]
db.feedback.update_one({"_id": ObjectId(fid)}, {"$set": update})
return jsonify({"message":"Updated"})
# delete feedback (owner or admin)
@feedback_bp.route("/<fid>", methods=["DELETE"])
@token_required
def delete_feedback(fid):
fb = db.feedback.find_one({"_id": ObjectId(fid)})
if not fb:
return jsonify({"error":"Not found"}), 404
if g.current_user.get("role") != "admin" and fb.get("student_id") != g.current_user["_id"]:
return jsonify({"error":"Not allowed"}), 403
db.feedback.delete_one({"_id": ObjectId(fid)})
return jsonify({"message":"Deleted"})
# admin export CSV
@feedback_bp.route("/export", methods=["GET"])
@token_required
@admin_required
def export_csv():
# optional filters
course = request.args.get("course")
rating = request.args.get("rating")
student_id = request.args.get("student_id")
query = {}
if course: query["course_id"] = course
if rating:
try: query["rating"] = int(rating)
except: pass
if student_id: query["student_id"] = student_id
docs = list(db.feedback.find(query).sort("created_at", -1))
# CSV
si = io.StringIO()
cw = csv.writer(si)
cw.writerow(["feedback_id","course_id","rating","message","student_id","student_name","created_at"])
for d in docs:
cw.writerow([
str(d.get("_id")),
d.get("course_id"),
d.get("rating"),
d.get("message"),
d.get("student_id"),
d.get("student_name"),
d.get("created_at").isoformat() if d.get("created_at") else ""
])
output = si.getvalue()
return Response(output, mimetype="text/csv",
headers={"Content-Disposition":"attachment;filename=feedbacks.csv"})