"""Flask-based ticketing system web application.""" from flask import Flask, redirect, render_template, request, url_for from models import Ticket, TicketPriority, TicketStatus from store import get_store app = Flask(__name__) # ── helper ─────────────────────────────────────────────────────── def _priorities() -> list[tuple[str, str]]: return [(p.value, p.name.replace("_", " ").title()) for p in TicketPriority] def _statuses() -> list[tuple[str, str]]: return [(s.value, s.name.replace("_", " ").title()) for s in TicketStatus] def _ticket_from_form() -> Ticket: return Ticket( title=request.form.get("title", "").strip(), description=request.form.get("description", "").strip(), priority=TicketPriority(request.form.get("priority", "medium")), status=TicketStatus(request.form.get("status", "open")), assignee=request.form.get("assignee", "").strip(), project=request.form.get("project", "").strip(), ) # ── routes ─────────────────────────────────────────────────────── @app.route("/") def index() -> str: store = get_store() status_filter = request.args.get("status", "") priority_filter = request.args.get("priority", "") project_filter = request.args.get("project", "") search = request.args.get("search", "") tickets = store.list_tickets( status=status_filter or None, priority=priority_filter or None, search=search or None, project=project_filter or None, ) counts = store.count_by_status() projects = store.get_projects() return render_template( "index.html", tickets=tickets, status_filter=status_filter, priority_filter=priority_filter, project_filter=project_filter, search=search, counts=counts, priorities=_priorities(), statuses=_statuses(), projects=projects, ) @app.route("/tickets/new", methods=["GET", "POST"]) def create_ticket() -> str: if request.method == "POST": ticket = _ticket_from_form() if not ticket.title: return render_template( "create.html", priorities=_priorities(), statuses=_statuses(), ticket=ticket, error="Title is required.", ) store = get_store() store.create_ticket(ticket) return redirect(url_for("index")) return render_template( "create.html", priorities=_priorities(), statuses=_statuses(), ticket=None, ) @app.route("/tickets/") def view_ticket(ticket_id: int) -> str: store = get_store() ticket = store.get_ticket(ticket_id) if ticket is None: return "Ticket not found", 404 return render_template( "detail.html", ticket=ticket, priorities=_priorities(), statuses=_statuses(), ) @app.route("/tickets//edit", methods=["GET", "POST"]) def edit_ticket(ticket_id: int) -> str: store = get_store() ticket = store.get_ticket(ticket_id) if ticket is None: return "Ticket not found", 404 if request.method == "POST": title = request.form.get("title", "").strip() if not title: return render_template( "edit.html", ticket=ticket, priorities=_priorities(), statuses=_statuses(), error="Title is required.", ) updates = { "title": title, "description": request.form.get("description", "").strip(), "priority": TicketPriority(request.form.get("priority", "medium")), "status": TicketStatus(request.form.get("status", "open")), "assignee": request.form.get("assignee", "").strip(), "project": request.form.get("project", "").strip(), } store.update_ticket(ticket_id, updates) return redirect(url_for("view_ticket", ticket_id=ticket_id)) return render_template( "edit.html", ticket=ticket, priorities=_priorities(), statuses=_statuses(), ) @app.route("/tickets//delete", methods=["POST"]) def delete_ticket(ticket_id: int) -> str: store = get_store() store.delete_ticket(ticket_id) return redirect(url_for("index")) # ── entrypoint ─────────────────────────────────────────────────── if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=5000)